Devicetree
 help / color / mirror / Atom feed
* Re: [RFC,v3 7/9] media: platform: Add Mediatek ISP P1 device driver
From: Jungo Lin @ 2019-08-07  2:11 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: devicetree, Sean Cheng (鄭昇弘),
	Mauro Carvalho Chehab, Rynn Wu (吳育恩),
	srv_heupstream, Rob Herring, Ryan Yu (余孟修),
	Frankie Chiu (邱文凱), Hans Verkuil,
	Matthias Brugger, Sj Huang,
	moderated list:ARM/Mediatek SoC support, Laurent Pinchart,
	ddavenport, Frederic Chen (陳俊元), list
In-Reply-To: <CAAFQd5D5m=gGViSY++r5uUS1+91y9=Gpcss1dEXrin_T07H+uQ@mail.gmail.com>

Hi, Tomasz:

On Tue, 2019-08-06 at 18:47 +0900, Tomasz Figa wrote:
> Hi Jungo,
> 
> On Fri, Jul 26, 2019 at 4:24 PM Jungo Lin <jungo.lin@mediatek.com> wrote:
> >
> > Hi, Tomasz:
> >
> > On Thu, 2019-07-25 at 18:23 +0900, Tomasz Figa wrote:
> > > .Hi Jungo,
> > >
> > > On Sat, Jul 20, 2019 at 6:58 PM Jungo Lin <jungo.lin@mediatek.com> wrote:
> > > >
> > > > Hi, Tomasz:
> > > >
> > > > On Wed, 2019-07-10 at 18:56 +0900, Tomasz Figa wrote:
> > > > > Hi Jungo,
> > > > >
> > > > > On Tue, Jun 11, 2019 at 11:53:42AM +0800, Jungo Lin wrote:
> [snip]

I just keep some questions to be clarified.
[snip]

> > > > > > +           isp_dev->meta0_vb2_index = meta0_vb2_index;
> > > > > > +           isp_dev->meta1_vb2_index = meta1_vb2_index;
> > > > > > +   } else {
> > > > > > +           if (irq_status & SOF_INT_ST) {
> > > > > > +                   isp_dev->current_frame = hw_frame_num;
> > > > > > +                   isp_dev->meta0_vb2_index = meta0_vb2_index;
> > > > > > +                   isp_dev->meta1_vb2_index = meta1_vb2_index;
> > > > > > +           }
> > > > > > +           irq_handle_notify_event(isp_dev, irq_status, dma_status, 1);
> > > > > > +   }
> > > > >
> > > > > The if and else blocks do almost the same things just in different order. Is
> > > > > it really expected?
> > > > >
> > > >
> > > > If we receive HW_PASS1_DON_ST & SOF_INT_ST IRQ events at the same time,
> > > > the correct sequence should be handle HW_PASS1_DON_ST firstly to check
> > > > any de-queued frame and update the next frame setting later.
> > > > Normally, this is a corner case or system performance issue.
> > >
> > > So it sounds like HW_PASS1_DON_ST means that all data from current
> > > frame has been written, right? If I understand your explanation above
> > > correctly, that would mean following handling of each interrupt:
> > >
> > > HW_PASS1_DON_ST:
> > >  - CQ executes with next CQ buffer to prepare for next frame. <- how
> > > is this handled? does the CQ hardware automatically receive this event
> > > from the ISP hadware?
> > >  - return VB2 buffers,
> > >  - complete requests.
> > >
> > > SOF_INT_ST:
> > >  - send VSYNC event to userspace,
> > >  - program next CQ buffer to CQ,
> > >
> > > SW_PASS1_DON_ST:
> > >  - reclaim CQ buffer and enqueue next frame to composing if available
> > >
> >
> > Sorry for our implementation of HW_PASS1_DON_ST.
> > It is confusing.
> > Below is the revised version based on your conclusion.
> > So in our new implemmenation, we just handle SOF_INT_ST &
> > SW_PASS1_DON_ST events. We just add one warning message for
> > HW_PASS1_DON_ST
> >
> > HW_PASS1_DON_ST:
> > - CQ executes with next CQ buffer to prepare for next frame.
> >
> > SOF_INT_ST:
> > - send VSYNC event to userspace,
> > - program next CQ buffer to CQ,
> >
> > SW_PASS1_DON_ST:
> > - reclaim CQ buffer and enqueue next frame to composing if available
> > - return VB2 buffers,
> > - complete requests.
> >
> > For CQ HW operations, it is listed below:
> >
> > a. The CQ buffer has two kinds of information
> >  - Which ISP registers needs to be updated.
> >  - Where the corresponding ISP register data to be read.
> > b. The CQ buffer loading procedure is triggered by HW_PASS1_DONT_ST IRQ
> > event periodically.
> >  - Normally, if the ISP HW receives the completed frame and it will
> > trigger W_PASS1_DONT_ST IRQ and perform CQ buffer loading immediately.
> > -  So the CQ buffer loading is performed by ISP HW automatically.
> > c. The ISP HW will read CQ base address register(REG_CQ_THR0_BASEADDR)
> > to decide which CQ buffer is loaded.
> >    - So we configure the next CQ base address in SOF.
> > d. For CQ buffer loading, CQ will read the ISP registers from CQ buffer
> > and update the ISP register values into HW.
> >    - SCP composer will compose one dummy CQ buffer and assign it to
> > REG_CQ_THR0_BASEADDR of each CQ buffer.
> >    - Dummy CQ buffer has no updated ISP registers comparing with other
> > CQ buffers.
> >    - With this design, if there is no updated new CQ buffer by driver
> > which may be caused no en-queue frames from user space. The CQ HW will
> > load dummy CQ buffer and do nothing.
> 
> Does the set of registers programmed by CQ include destination buffer
> addresses to? If yes, we would end up overwriting previous frames if
> no new buffers are provided.
> 

Yes, the buffer addresses are changed per frame request. We need to
compose CQ to include these DMA destination addresses. For your concern,
we have DMA flow buffer control (FBC) in HW. If there is no FBC counter
increased due to no buffer for each DMA, the ISP HW doesn't output the
data to the corresponding DMA address.

Below is the simple descriptor of CQ buffer.
a. ISP registers in tuning buffer, including 3A registers.
b. All capture buffers informations.
   - DMA buffer destination address
   - FBC counter
c. Some specif ISP registers for meta DMAs, such as LCE or LMVO.
d. frame sequence number register

> > f. The CQ buffer loading is guaranteed by HW to finish before the next
> > SOF.
> >
> 
> Okay, thanks a lot for the explanation. This is much more clear now.
> 
> [snip]
> > > > > > +static const struct dev_pm_ops mtk_isp_pm_ops = {
> > > > > > +   SET_SYSTEM_SLEEP_PM_OPS(mtk_isp_suspend, mtk_isp_resume)
> > > > > > +   SET_RUNTIME_PM_OPS(mtk_isp_suspend, mtk_isp_resume, NULL)
> > > > >
> > > > > For V4L2 drivers system and runtime PM ops would normally be completely
> > > > > different. Runtime PM ops would be called when the hardware is idle already
> > > > > or is about to become active. System PM ops would be called at system power
> > > > > state change and the hardware might be both idle or active. Please also see
> > > > > my comments to mtk_isp_suspend() and mtk_isp_resume() above.
> > > > >
> > > >
> > > > Here is the new implementation. It should be clear to show the
> > > > difference between system and runtime PM ops.
> > > >
> > > > static const struct dev_pm_ops mtk_isp_pm_ops = {
> > > >         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > > >                                 pm_runtime_force_resume)
> > > >         SET_RUNTIME_PM_OPS(mtk_isp_runtime_suspend, mtk_isp_runtime_resume,
> > > > NULL)
> > > > };
> > >
> > > That's still not correct. In runtime suspend/resume ops we already are
> > > not streaming anymore, because we call pm_runtime_get/put_*() when
> > > starting and stopping streaming. In system suspend/resume ops we might
> > > be streaming and that's when we need to stop the hardware and wait for
> > > it to finish. Please implement these ops separately.
> > >
> > > Best regards,
> > > Tomasz
> >
> >
> > Ok, got your point.
> > Below is the new implementation for your review.
> >
> > static int mtk_isp_pm_suspend(struct device *dev)
> > {
> >         struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> >         u32 val;
> >         int ret;
> >
> >         dev_dbg(dev, "- %s\n", __func__);
> >
> >         /* Check ISP is streaming or not */
> >         if (!p1_dev->cam_dev.streaming)
> >                 goto done;
> 
> We would normally check here for pm_runtime_suspended(). Although they
> both should be equivalent. Still, there is no need to call
> pm_runtime_force_suspend() if the latter is true, so we could just
> return 0 instantly.
> 

Ok, here is the fixed version.

static int mtk_isp_pm_suspend(struct device *dev)
{
	struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
	u32 val;
	int ret;

	dev_dbg(dev, "- %s\n", __func__);

	if (pm_runtime_suspended(dev))
		return 0;

	/* Disable ISP's view finder and wait for TG idle */
	dev_dbg(dev, "cam suspend, disable VF\n");
	val = readl(p1_dev->regs + REG_TG_VF_CON);
	writel(val & (~TG_VF_CON_VFDATA_EN), p1_dev->regs + REG_TG_VF_CON);
	ret = readl_poll_timeout_atomic(p1_dev->regs + REG_TG_INTER_ST, val,
					(val & TG_CS_MASK) == TG_IDLE_ST,
					USEC_PER_MSEC, MTK_ISP_STOP_HW_TIMEOUT);
	if (ret)
		dev_warn(dev, "can't stop HW:%d:0x%x\n", ret, val);

	/* Disable CMOS */
	val = readl(p1_dev->regs + REG_TG_SEN_MODE);
	writel(val & (~TG_SEN_MODE_CMOS_EN), p1_dev->regs + REG_TG_SEN_MODE);

	/* Force ISP HW to idle */
	ret = pm_runtime_force_suspend(dev);
	if (ret)
		return ret;

	return 0;
}
[snip]

> > static int mtk_isp_pm_resume(struct device *dev)
> > {
> >         struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> >         u32 val;
> >         int ret;
> >
> >         dev_dbg(dev, "- %s\n", __func__);
> >
> >         /* Force ISP HW to resume if needed */
> >         ret = pm_runtime_force_resume(dev);
> >         if (ret)
> >                 return ret;
> 
> We should do this conditionally based on what pm_runtime_suspended()
> returns. If it's non-zero then we can just return 0 instantly.
> 

Ok, here is the fixed version.

static int mtk_isp_pm_resume(struct device *dev)
{
	struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
	u32 val;
	int ret;

	dev_dbg(dev, "- %s\n", __func__);

	if (pm_runtime_suspended(dev))
		return 0;

	/* Force ISP HW to resume */
	ret = pm_runtime_force_resume(dev);
	if (ret)
		return ret;

	/* Enable CMOS */
	dev_dbg(dev, "cam resume, enable CMOS/VF\n");
	val = readl(p1_dev->regs + REG_TG_SEN_MODE);
	writel(val | TG_SEN_MODE_CMOS_EN, p1_dev->regs + REG_TG_SEN_MODE);

	/* Enable VF */
	val = readl(p1_dev->regs + REG_TG_VF_CON);
	writel(val | TG_VF_CON_VFDATA_EN, p1_dev->regs + REG_TG_VF_CON);

	return 0;
}

[snip]

> > static int mtk_isp_runtime_suspend(struct device *dev)
> > {
> >         struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> >
> >         dev_dbg(dev, "- %s\n", __func__);
> >
> >         if (pm_runtime_suspended(dev))
> >                 return 0;
> 
> Sorry, I guess I wasn't clear in my reply. It's not possible to get
> this callback called if the device is already runtime suspended.
> 

Ok, got it. Need to remove pm_runtime_suspended(dev) checking and move
it into mtk_isp_pm_* functions. If I still don't get your point, could
you kindly provide one sample driver for reference? Based on current
implementation, it is similar to below drivers.
https://elixir.bootlin.com/linux/latest/source/drivers/media/platform/mtk-mdp/mtk_mdp_core.c#L255
https://elixir.bootlin.com/linux/latest/source/drivers/media/platform/exynos4-is/fimc-is-i2c.c#L113


static int mtk_isp_runtime_suspend(struct device *dev)
{
	struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);

	dev_dbg(dev, "%s:disable clock\n", __func__);
	clk_bulk_disable_unprepare(p1_dev->num_clks, p1_dev->clks);

	return 0;
}

[snip]

> > static int mtk_isp_runtime_resume(struct device *dev)
> > {
> >         struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> >         int ret;
> >
> >         dev_dbg(dev, "- %s\n", __func__);
> >
> >         if (pm_runtime_suspended(dev))
> >                 return 0;
> 
> In this case the above call would always return non-zero, so the
> behavior wouldn't be very good.
> 

Same as above.

static int mtk_isp_runtime_resume(struct device *dev)
{
	struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
	int ret;

	dev_dbg(dev, "%s:enable clock\n", __func__);
	ret = clk_bulk_prepare_enable(p1_dev->num_clks, p1_dev->clks);
	if (ret) {
		dev_err(dev, "failed to enable clock:%d\n", ret);
		return ret;
	}

	return 0;
}

Thanks for your further comments on these issues.

Best regards,

Jugno

> Best regards,
> Tomasz
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* [PATCH] of/platform: Fix device_links_supplier_sync_state_resume() warning
From: Saravana Kannan @ 2019-08-07  2:05 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rob Herring, Frank Rowand
  Cc: Saravana Kannan, Qian Cai, kernel-team, devicetree, linux-kernel

In platforms/devices which have CONFIG_OF turned on but don't have a
populated DT, the calls to device_links_supplier_sync_state_pause() and
device_links_supplier_sync_state_resume() can get mismatched. This will
cause a warning during boot. Fix the warning by making sure the calls are
matched even in that case.

Reported-by: Qian Cai <cai@lca.pw>
Signed-off-by: Saravana Kannan <saravanak@google.com>
---
 drivers/of/platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index a2a4e4b79d43..e5f7e40df439 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -723,7 +723,8 @@ arch_initcall_sync(of_platform_default_populate_init);
 
 static int __init of_platform_sync_state_init(void)
 {
-	device_links_supplier_sync_state_resume();
+	if (of_have_populated_dt())
+		device_links_supplier_sync_state_resume();
 	return 0;
 }
 late_initcall_sync(of_platform_sync_state_init);
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* Re: "of/platform: Pause/resume sync state during init and of_platform_populate()" with a warning on arm64
From: Qian Cai @ 2019-08-07  1:56 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Greg Kroah-Hartman, linux-arm-kernel, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux List Kernel Mailing
In-Reply-To: <CAGETcx_KZNMY1Zs=G=HGPfsUA4Fen_m8R4L9jNHtWrZerabwxg@mail.gmail.com>



> On Aug 6, 2019, at 9:50 PM, Saravana Kannan <saravanak@google.com> wrote:
> 
> Thanks for confirming. I didn't think ARM64 could even boot without
> DT. I'll send a fix right away.
> 
> Any chance you can let us know what device this was tested on?

It is a HPE Apollo 70 arm64 server.

https://h20195.www2.hpe.com/v2/gethtml.aspx?docname=a00039978enw

> 
> -Saravana
> 
> 
> 
> -Saravana
> 
> On Tue, Aug 6, 2019 at 6:46 PM Qian Cai <cai@lca.pw> wrote:
>> 
>> 
>> 
>>> On Aug 6, 2019, at 9:22 PM, Saravana Kannan <saravanak@google.com> wrote:
>>> 
>>> On Tue, Aug 6, 2019 at 5:46 PM Qian Cai <cai@lca.pw> wrote:
>>>> 
>>>> It looks like the linux-next commit “of/platform: Pause/resume sync state during init and of_platform_populate()” [1]
>>>> Introduced a warning while booting arm64.
>>>> 
>>>> [1] https://lore.kernel.org/lkml/20190731221721.187713-6-saravanak@google.com/
>>>> 
>>>> [   93.449300][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
>>>> [   93.464873][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for cmdq
>>>> [   93.485481][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for evtq
>>>> [   93.496320][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: option mask 0x2
>>>> [   93.502917][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
>>>> [   93.621818][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for cmdq
>>>> [   93.643000][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for evtq
>>>> [   94.519445][    T1] libphy: Fixed MDIO Bus: probed
>>>> [   94.524649][    T1] EFI Variables Facility v0.08 2004-May-17
>>>> [   94.601166][    T1] NET: Registered protocol family 17
>>>> [   94.766008][    T1] zswap: loaded using pool lzo/zbud
>>>> [   94.774745][    T1] kmemleak: Kernel memory leak detector initialized (mempool size: 16384)
>>>> [   94.774756][ T1699] kmemleak: Automatic memory scanning thread started
>>>> [   94.812338][ T1368] pcieport 0000:0f:00.0: Adding to iommu group 0
>>>> [   94.984466][    T1] ------------[ cut here ]------------
>>>> [   94.989827][    T1] Unmatched sync_state pause/resume!
>>>> [   94.989894][    T1] WARNING: CPU: 25 PID: 1 at drivers/base/core.c:691 device_links_supplier_sync_state_resume+0x100/0x128
>>>> [   95.006062][    T1] Modules linked in:
>>>> [   95.009815][    T1] CPU: 25 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc3-next-20190806+ #11
>>>> [   95.018161][    T1] Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
>>>> [   95.028593][    T1] pstate: 60400009 (nZCv daif +PAN -UAO)
>>>> [   95.034077][    T1] pc : device_links_supplier_sync_state_resume+0x100/0x128
>>>> [   95.041124][    T1] lr : device_links_supplier_sync_state_resume+0x100/0x128
>>>> [   95.048167][    T1] sp : 34ff800806e6fbc0
>>>> [   95.052172][    T1] x29: 34ff800806e6fc00 x28: 0000000000000000
>>>> [   95.058177][    T1] x27: 0000000000000000 x26: 0000000000000000
>>>> [   95.064181][    T1] x25: 0000000000000038 x24: 0000000000000000
>>>> [   95.070185][    T1] x23: 0000000000000000 x22: 0000000000000019
>>>> [   95.076189][    T1] x21: 0000000000000000 x20: f9ff808b804e6c50
>>>> [   95.082193][    T1] x19: ffff100014a6e600 x18: 0000000000000040
>>>> [   95.088197][    T1] x17: 0000000000000000 x16: 86ff80099d581b50
>>>> [   95.094201][    T1] x15: 0000000000000000 x14: ffff100010086d1c
>>>> [   95.100205][    T1] x13: ffff1000109d8688 x12: ffffffffffffffff
>>>> [   95.106209][    T1] x11: 00000000000000f9 x10: ffff0808b804e6c6
>>>> [   95.112213][    T1] x9 : 4b71ad522c851d00 x8 : 4b71ad522c851d00
>>>> [   95.118217][    T1] x7 : 6170206574617473 x6 : ffff100014076972
>>>> [   95.124221][    T1] x5 : 34ff800806e6f8f0 x4 : 000000000000000f
>>>> [   95.130225][    T1] x3 : ffff1000101bfa5c x2 : 0000000000000001
>>>> [   95.136229][    T1] x1 : 0000000000000001 x0 : 0000000000000022
>>>> [   95.142233][    T1] Call trace:
>>>> [   95.145374][    T1]  device_links_supplier_sync_state_resume+0x100/0x128
>>>> [   95.152074][    T1]  of_platform_sync_state_init+0x10/0x1c
>>>> [   95.157557][    T1]  do_one_initcall+0x2f8/0x600
>>>> [   95.162172][    T1]  do_initcall_level+0x37c/0x3fc
>>>> [   95.166959][    T1]  do_basic_setup+0x34/0x4c
>>>> [   95.171313][    T1]  kernel_init_freeable+0x188/0x24c
>>>> [   95.176363][    T1]  kernel_init+0x18/0x334
>>>> [   95.180543][    T1]  ret_from_fork+0x10/0x18
>>>> [   95.184809][    T1] ---[ end trace a9ea68c902540fe5 ]---
>>>> [   95.269085][    T1] Freeing unused kernel memory: 28672K
>>>> [  101.069860][    T1] Checked W+X mappings: passed, no W+X pages found
>>>> [  101.076265][    T1] Run /init as init process
>>>> [  101.186359][    T1] systemd[1]: System time before build time, advancing clock.
>>> 
>>> 
>>> I tested it again on my device (on an older kernel) and I don't see
>>> this warning. Is this on an ARM64 target without a populated DT?
>> 
>> Probably, /sys/firmware/devicetree is all empty.
>> 
>>> That's the only thing I can see that could cause this warning.
>>> 
>>> This is literally the code with the matching pause/resume. I can't
>>> think of any other way the pause/resume could have ended up not
>>> matching.
>>> 
>>> static int __init of_platform_default_populate_init(void)
>>> {
>>>       struct device_node *node;
>>> 
>>>       if (!of_have_populated_dt())
>>>               return -ENODEV;
>>> 
>>>       platform_bus_type.add_links = of_link_to_suppliers;
>>>       device_links_supplier_sync_state_pause(); <=========== PAUSE
>>>       /*
>>>        * Handle certain compatibles explicitly, since we don't want to create
>>>        * platform_devices for every node in /reserved-memory with a
>>>        * "compatible",
>>>        */
>>>       for_each_matching_node(node, reserved_mem_matches)
>>>               of_platform_device_create(node, NULL, NULL);
>>> 
>>>       node = of_find_node_by_path("/firmware");
>>>       if (node) {
>>>               of_platform_populate(node, NULL, NULL, NULL);
>>>               of_node_put(node);
>>>       }
>>> 
>>>       /* Populate everything else. */
>>>       of_platform_default_populate(NULL, NULL, NULL);
>>> 
>>>       return 0;
>>> }
>>> arch_initcall_sync(of_platform_default_populate_init);
>>> 
>>> static int __init of_platform_sync_state_init(void)
>>> {
>>>       device_links_supplier_sync_state_resume(); <========= RESUME
>>>       return 0;
>>> }
>>> late_initcall_sync(of_platform_sync_state_init);
>>> 
>>> Thanks,
>>> Saravana
>> 

^ permalink raw reply

* Re: "of/platform: Pause/resume sync state during init and of_platform_populate()" with a warning on arm64
From: Saravana Kannan @ 2019-08-07  1:50 UTC (permalink / raw)
  To: Qian Cai
  Cc: Greg Kroah-Hartman, linux-arm-kernel, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux List Kernel Mailing
In-Reply-To: <6326D2D1-8641-48D1-BDD5-4F4B8BADB286@lca.pw>

Thanks for confirming. I didn't think ARM64 could even boot without
DT. I'll send a fix right away.

Any chance you can let us know what device this was tested on?

-Saravana



-Saravana

On Tue, Aug 6, 2019 at 6:46 PM Qian Cai <cai@lca.pw> wrote:
>
>
>
> > On Aug 6, 2019, at 9:22 PM, Saravana Kannan <saravanak@google.com> wrote:
> >
> > On Tue, Aug 6, 2019 at 5:46 PM Qian Cai <cai@lca.pw> wrote:
> >>
> >> It looks like the linux-next commit “of/platform: Pause/resume sync state during init and of_platform_populate()” [1]
> >> Introduced a warning while booting arm64.
> >>
> >> [1] https://lore.kernel.org/lkml/20190731221721.187713-6-saravanak@google.com/
> >>
> >> [   93.449300][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
> >> [   93.464873][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for cmdq
> >> [   93.485481][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for evtq
> >> [   93.496320][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: option mask 0x2
> >> [   93.502917][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
> >> [   93.621818][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for cmdq
> >> [   93.643000][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for evtq
> >> [   94.519445][    T1] libphy: Fixed MDIO Bus: probed
> >> [   94.524649][    T1] EFI Variables Facility v0.08 2004-May-17
> >> [   94.601166][    T1] NET: Registered protocol family 17
> >> [   94.766008][    T1] zswap: loaded using pool lzo/zbud
> >> [   94.774745][    T1] kmemleak: Kernel memory leak detector initialized (mempool size: 16384)
> >> [   94.774756][ T1699] kmemleak: Automatic memory scanning thread started
> >> [   94.812338][ T1368] pcieport 0000:0f:00.0: Adding to iommu group 0
> >> [   94.984466][    T1] ------------[ cut here ]------------
> >> [   94.989827][    T1] Unmatched sync_state pause/resume!
> >> [   94.989894][    T1] WARNING: CPU: 25 PID: 1 at drivers/base/core.c:691 device_links_supplier_sync_state_resume+0x100/0x128
> >> [   95.006062][    T1] Modules linked in:
> >> [   95.009815][    T1] CPU: 25 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc3-next-20190806+ #11
> >> [   95.018161][    T1] Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
> >> [   95.028593][    T1] pstate: 60400009 (nZCv daif +PAN -UAO)
> >> [   95.034077][    T1] pc : device_links_supplier_sync_state_resume+0x100/0x128
> >> [   95.041124][    T1] lr : device_links_supplier_sync_state_resume+0x100/0x128
> >> [   95.048167][    T1] sp : 34ff800806e6fbc0
> >> [   95.052172][    T1] x29: 34ff800806e6fc00 x28: 0000000000000000
> >> [   95.058177][    T1] x27: 0000000000000000 x26: 0000000000000000
> >> [   95.064181][    T1] x25: 0000000000000038 x24: 0000000000000000
> >> [   95.070185][    T1] x23: 0000000000000000 x22: 0000000000000019
> >> [   95.076189][    T1] x21: 0000000000000000 x20: f9ff808b804e6c50
> >> [   95.082193][    T1] x19: ffff100014a6e600 x18: 0000000000000040
> >> [   95.088197][    T1] x17: 0000000000000000 x16: 86ff80099d581b50
> >> [   95.094201][    T1] x15: 0000000000000000 x14: ffff100010086d1c
> >> [   95.100205][    T1] x13: ffff1000109d8688 x12: ffffffffffffffff
> >> [   95.106209][    T1] x11: 00000000000000f9 x10: ffff0808b804e6c6
> >> [   95.112213][    T1] x9 : 4b71ad522c851d00 x8 : 4b71ad522c851d00
> >> [   95.118217][    T1] x7 : 6170206574617473 x6 : ffff100014076972
> >> [   95.124221][    T1] x5 : 34ff800806e6f8f0 x4 : 000000000000000f
> >> [   95.130225][    T1] x3 : ffff1000101bfa5c x2 : 0000000000000001
> >> [   95.136229][    T1] x1 : 0000000000000001 x0 : 0000000000000022
> >> [   95.142233][    T1] Call trace:
> >> [   95.145374][    T1]  device_links_supplier_sync_state_resume+0x100/0x128
> >> [   95.152074][    T1]  of_platform_sync_state_init+0x10/0x1c
> >> [   95.157557][    T1]  do_one_initcall+0x2f8/0x600
> >> [   95.162172][    T1]  do_initcall_level+0x37c/0x3fc
> >> [   95.166959][    T1]  do_basic_setup+0x34/0x4c
> >> [   95.171313][    T1]  kernel_init_freeable+0x188/0x24c
> >> [   95.176363][    T1]  kernel_init+0x18/0x334
> >> [   95.180543][    T1]  ret_from_fork+0x10/0x18
> >> [   95.184809][    T1] ---[ end trace a9ea68c902540fe5 ]---
> >> [   95.269085][    T1] Freeing unused kernel memory: 28672K
> >> [  101.069860][    T1] Checked W+X mappings: passed, no W+X pages found
> >> [  101.076265][    T1] Run /init as init process
> >> [  101.186359][    T1] systemd[1]: System time before build time, advancing clock.
> >
> >
> > I tested it again on my device (on an older kernel) and I don't see
> > this warning. Is this on an ARM64 target without a populated DT?
>
> Probably, /sys/firmware/devicetree is all empty.
>
> > That's the only thing I can see that could cause this warning.
> >
> > This is literally the code with the matching pause/resume. I can't
> > think of any other way the pause/resume could have ended up not
> > matching.
> >
> > static int __init of_platform_default_populate_init(void)
> > {
> >        struct device_node *node;
> >
> >        if (!of_have_populated_dt())
> >                return -ENODEV;
> >
> >        platform_bus_type.add_links = of_link_to_suppliers;
> >        device_links_supplier_sync_state_pause(); <=========== PAUSE
> >        /*
> >         * Handle certain compatibles explicitly, since we don't want to create
> >         * platform_devices for every node in /reserved-memory with a
> >         * "compatible",
> >         */
> >        for_each_matching_node(node, reserved_mem_matches)
> >                of_platform_device_create(node, NULL, NULL);
> >
> >        node = of_find_node_by_path("/firmware");
> >        if (node) {
> >                of_platform_populate(node, NULL, NULL, NULL);
> >                of_node_put(node);
> >        }
> >
> >        /* Populate everything else. */
> >        of_platform_default_populate(NULL, NULL, NULL);
> >
> >        return 0;
> > }
> > arch_initcall_sync(of_platform_default_populate_init);
> >
> > static int __init of_platform_sync_state_init(void)
> > {
> >        device_links_supplier_sync_state_resume(); <========= RESUME
> >        return 0;
> > }
> > late_initcall_sync(of_platform_sync_state_init);
> >
> > Thanks,
> > Saravana
>

^ permalink raw reply

* Re: "of/platform: Pause/resume sync state during init and of_platform_populate()" with a warning on arm64
From: Qian Cai @ 2019-08-07  1:46 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Greg Kroah-Hartman, linux-arm-kernel, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux List Kernel Mailing
In-Reply-To: <CAGETcx_TYxgohR7C5SRRbSmfKNhS90i64KjtA38N19g_Kz3euA@mail.gmail.com>



> On Aug 6, 2019, at 9:22 PM, Saravana Kannan <saravanak@google.com> wrote:
> 
> On Tue, Aug 6, 2019 at 5:46 PM Qian Cai <cai@lca.pw> wrote:
>> 
>> It looks like the linux-next commit “of/platform: Pause/resume sync state during init and of_platform_populate()” [1]
>> Introduced a warning while booting arm64.
>> 
>> [1] https://lore.kernel.org/lkml/20190731221721.187713-6-saravanak@google.com/
>> 
>> [   93.449300][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
>> [   93.464873][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for cmdq
>> [   93.485481][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for evtq
>> [   93.496320][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: option mask 0x2
>> [   93.502917][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
>> [   93.621818][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for cmdq
>> [   93.643000][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for evtq
>> [   94.519445][    T1] libphy: Fixed MDIO Bus: probed
>> [   94.524649][    T1] EFI Variables Facility v0.08 2004-May-17
>> [   94.601166][    T1] NET: Registered protocol family 17
>> [   94.766008][    T1] zswap: loaded using pool lzo/zbud
>> [   94.774745][    T1] kmemleak: Kernel memory leak detector initialized (mempool size: 16384)
>> [   94.774756][ T1699] kmemleak: Automatic memory scanning thread started
>> [   94.812338][ T1368] pcieport 0000:0f:00.0: Adding to iommu group 0
>> [   94.984466][    T1] ------------[ cut here ]------------
>> [   94.989827][    T1] Unmatched sync_state pause/resume!
>> [   94.989894][    T1] WARNING: CPU: 25 PID: 1 at drivers/base/core.c:691 device_links_supplier_sync_state_resume+0x100/0x128
>> [   95.006062][    T1] Modules linked in:
>> [   95.009815][    T1] CPU: 25 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc3-next-20190806+ #11
>> [   95.018161][    T1] Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
>> [   95.028593][    T1] pstate: 60400009 (nZCv daif +PAN -UAO)
>> [   95.034077][    T1] pc : device_links_supplier_sync_state_resume+0x100/0x128
>> [   95.041124][    T1] lr : device_links_supplier_sync_state_resume+0x100/0x128
>> [   95.048167][    T1] sp : 34ff800806e6fbc0
>> [   95.052172][    T1] x29: 34ff800806e6fc00 x28: 0000000000000000
>> [   95.058177][    T1] x27: 0000000000000000 x26: 0000000000000000
>> [   95.064181][    T1] x25: 0000000000000038 x24: 0000000000000000
>> [   95.070185][    T1] x23: 0000000000000000 x22: 0000000000000019
>> [   95.076189][    T1] x21: 0000000000000000 x20: f9ff808b804e6c50
>> [   95.082193][    T1] x19: ffff100014a6e600 x18: 0000000000000040
>> [   95.088197][    T1] x17: 0000000000000000 x16: 86ff80099d581b50
>> [   95.094201][    T1] x15: 0000000000000000 x14: ffff100010086d1c
>> [   95.100205][    T1] x13: ffff1000109d8688 x12: ffffffffffffffff
>> [   95.106209][    T1] x11: 00000000000000f9 x10: ffff0808b804e6c6
>> [   95.112213][    T1] x9 : 4b71ad522c851d00 x8 : 4b71ad522c851d00
>> [   95.118217][    T1] x7 : 6170206574617473 x6 : ffff100014076972
>> [   95.124221][    T1] x5 : 34ff800806e6f8f0 x4 : 000000000000000f
>> [   95.130225][    T1] x3 : ffff1000101bfa5c x2 : 0000000000000001
>> [   95.136229][    T1] x1 : 0000000000000001 x0 : 0000000000000022
>> [   95.142233][    T1] Call trace:
>> [   95.145374][    T1]  device_links_supplier_sync_state_resume+0x100/0x128
>> [   95.152074][    T1]  of_platform_sync_state_init+0x10/0x1c
>> [   95.157557][    T1]  do_one_initcall+0x2f8/0x600
>> [   95.162172][    T1]  do_initcall_level+0x37c/0x3fc
>> [   95.166959][    T1]  do_basic_setup+0x34/0x4c
>> [   95.171313][    T1]  kernel_init_freeable+0x188/0x24c
>> [   95.176363][    T1]  kernel_init+0x18/0x334
>> [   95.180543][    T1]  ret_from_fork+0x10/0x18
>> [   95.184809][    T1] ---[ end trace a9ea68c902540fe5 ]---
>> [   95.269085][    T1] Freeing unused kernel memory: 28672K
>> [  101.069860][    T1] Checked W+X mappings: passed, no W+X pages found
>> [  101.076265][    T1] Run /init as init process
>> [  101.186359][    T1] systemd[1]: System time before build time, advancing clock.
> 
> 
> I tested it again on my device (on an older kernel) and I don't see
> this warning. Is this on an ARM64 target without a populated DT?

Probably, /sys/firmware/devicetree is all empty.

> That's the only thing I can see that could cause this warning.
> 
> This is literally the code with the matching pause/resume. I can't
> think of any other way the pause/resume could have ended up not
> matching.
> 
> static int __init of_platform_default_populate_init(void)
> {
>        struct device_node *node;
> 
>        if (!of_have_populated_dt())
>                return -ENODEV;
> 
>        platform_bus_type.add_links = of_link_to_suppliers;
>        device_links_supplier_sync_state_pause(); <=========== PAUSE
>        /*
>         * Handle certain compatibles explicitly, since we don't want to create
>         * platform_devices for every node in /reserved-memory with a
>         * "compatible",
>         */
>        for_each_matching_node(node, reserved_mem_matches)
>                of_platform_device_create(node, NULL, NULL);
> 
>        node = of_find_node_by_path("/firmware");
>        if (node) {
>                of_platform_populate(node, NULL, NULL, NULL);
>                of_node_put(node);
>        }
> 
>        /* Populate everything else. */
>        of_platform_default_populate(NULL, NULL, NULL);
> 
>        return 0;
> }
> arch_initcall_sync(of_platform_default_populate_init);
> 
> static int __init of_platform_sync_state_init(void)
> {
>        device_links_supplier_sync_state_resume(); <========= RESUME
>        return 0;
> }
> late_initcall_sync(of_platform_sync_state_init);
> 
> Thanks,
> Saravana

^ permalink raw reply

* Re: [PATCH v3 5/5] ASoC: dt-bindings: Introduce compatible strings for 7ULP and 8MQ
From: Nicolin Chen @ 2019-08-07  1:42 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: broonie, l.stach, mihai.serban, alsa-devel, timur, shengjiu.wang,
	angus, tiwai, linux-imx, kernel, festevam, linux-kernel,
	devicetree, robh
In-Reply-To: <20190806151214.6783-6-daniel.baluta@nxp.com>

On Tue, Aug 06, 2019 at 06:12:14PM +0300, Daniel Baluta wrote:
> For i.MX7ULP and i.MX8MQ register map is changed. Add two new compatbile
> strings to differentiate this.
> 
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>

Looks good to me. As long as one of DT maintainers acks,

Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>

Thanks

> ---
>  Documentation/devicetree/bindings/sound/fsl-sai.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
> index 2e726b983845..e61c0dc1fc0b 100644
> --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
> +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
> @@ -8,7 +8,8 @@ codec/DSP interfaces.
>  Required properties:
>  
>    - compatible		: Compatible list, contains "fsl,vf610-sai",
> -			  "fsl,imx6sx-sai" or "fsl,imx6ul-sai"
> +			  "fsl,imx6sx-sai", "fsl,imx6ul-sai",
> +			  "fsl,imx7ulp-sai" or "fsl,imx8mq-sai".
>  
>    - reg			: Offset and length of the register set for the device.
>  
> -- 
> 2.17.1
> 

^ permalink raw reply

* Re: [PATCH v3 3/5] ASoC: fsl_sai: Add support for SAI new version
From: Nicolin Chen @ 2019-08-07  1:40 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: broonie, l.stach, mihai.serban, alsa-devel, timur, shengjiu.wang,
	angus, tiwai, linux-imx, kernel, festevam, linux-kernel,
	devicetree, robh, Mihai Serban
In-Reply-To: <20190806151214.6783-4-daniel.baluta@nxp.com>

On Tue, Aug 06, 2019 at 06:12:12PM +0300, Daniel Baluta wrote:
> New IP version introduces Version ID and Parameter registers
> and optionally added Timestamp feature.
> 
> VERID and PARAM registers are placed at the top of registers
> address space and some registers are shifted according to
> the following table:
> 
> Tx/Rx data registers and Tx/Rx FIFO registers keep their
> addresses, all other registers are shifted by 8.
> 
> SAI Memory map is described in chapter 13.10.4.1.1 I2S Memory map
> of the Reference Manual [1].
> 
> In order to make as less changes as possible we attach an offset
> to each register offset to each changed register definition. The
> offset is read from each board private data.
> 
> [1]https://cache.nxp.com/secured/assets/documents/en/reference-manual/IMX8MDQLQRM.pdf?__gda__=1563728701_38bea7f0f726472cc675cb141b91bec7&fileExt=.pdf
> 
> Signed-off-by: Mihai Serban <mihai.serban@nxp.com>
> [initial coding in the NXP internal tree]
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> [bugfixing and cleanups]
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
> [adapted to linux-next]

Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>

One small request that we can do with a separate patch later:

>  struct fsl_sai_soc_data {
>  	bool use_imx_pcm;
>  	unsigned int fifo_depth;
> +	unsigned int reg_offset;
>  };

I think we need a list of comments for the structure defines.
It might be okay for the old two entries but reg_offset isn't
that explicit any more.

^ permalink raw reply

* Re: [PATCH v3 3/5] RISC-V: Fix unsupported isa string info.
From: Paul Walmsley @ 2019-08-07  1:26 UTC (permalink / raw)
  To: Atish Patra
  Cc: info@metux.net, allison@lohutok.net, palmer@sifive.com,
	aou@eecs.berkeley.edu, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, tglx@linutronix.de,
	daniel.lezcano@linaro.org, Anup Patel, mark.rutland@arm.com,
	robh+dt@kernel.org, johan@kernel.org, tiny.windzz@gmail.com,
	gregkh@linuxfoundation.org, gary@garyguo.net,
	linux-riscv@lists.infradead.org
In-Reply-To: <1e23ef1face9d323fda4b756811f922caa5f7689.camel@wdc.com>

On Wed, 7 Aug 2019, Atish Patra wrote:

> On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
> 
> > Seems like the "su" should be dropped from mandatory_ext.  What do you 
> > think?
> > 
> 
> Yup. As DT binding only mention imafdc, mandatory extensions should
> contain only that and just consider "su" extensions are considered as
> implicit as we are running Linux. 

Discussing this with Andrew and Palmer, it looks like "su" is currently 
non-compliant.  Section 22.6 of the user-level specification states that 
the "s" character indicates that a longer standard supervisor extension 
name will follow.  So far I don't think any of these have been defined.

> Do you think QEMU DT should be updated to reflect that ?

Yes.

> > There's no Kconfig option by this name, and we're requiring
> > compressed 
> 
> Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.
> 
> > instruction support as part of the RISC-V Linux baseline.  Could you 
> > share the rationale behind this?
> 
> I think I added this check at the config file. Looking at the Kconfig,
> RISCV_ISA_C is always enabled. So we can drop this.

OK great.  Do you want to resend an updated patch, or would you like me to 
fix it up here?

I'll also send a patch to drop CONFIG_RISCV_ISA_C.


- Paul

^ permalink raw reply

* Re: "of/platform: Pause/resume sync state during init and of_platform_populate()" with a warning on arm64
From: Saravana Kannan @ 2019-08-07  1:22 UTC (permalink / raw)
  To: Qian Cai
  Cc: Greg Kroah-Hartman, linux-arm-kernel, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux List Kernel Mailing
In-Reply-To: <B4B0AD7F-FA0F-4DA0-9A8B-EAE1CEE11759@lca.pw>

On Tue, Aug 6, 2019 at 5:46 PM Qian Cai <cai@lca.pw> wrote:
>
> It looks like the linux-next commit “of/platform: Pause/resume sync state during init and of_platform_populate()” [1]
> Introduced a warning while booting arm64.
>
> [1] https://lore.kernel.org/lkml/20190731221721.187713-6-saravanak@google.com/
>
> [   93.449300][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
> [   93.464873][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for cmdq
> [   93.485481][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for evtq
> [   93.496320][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: option mask 0x2
> [   93.502917][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
> [   93.621818][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for cmdq
> [   93.643000][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for evtq
> [   94.519445][    T1] libphy: Fixed MDIO Bus: probed
> [   94.524649][    T1] EFI Variables Facility v0.08 2004-May-17
> [   94.601166][    T1] NET: Registered protocol family 17
> [   94.766008][    T1] zswap: loaded using pool lzo/zbud
> [   94.774745][    T1] kmemleak: Kernel memory leak detector initialized (mempool size: 16384)
> [   94.774756][ T1699] kmemleak: Automatic memory scanning thread started
> [   94.812338][ T1368] pcieport 0000:0f:00.0: Adding to iommu group 0
> [   94.984466][    T1] ------------[ cut here ]------------
> [   94.989827][    T1] Unmatched sync_state pause/resume!
> [   94.989894][    T1] WARNING: CPU: 25 PID: 1 at drivers/base/core.c:691 device_links_supplier_sync_state_resume+0x100/0x128
> [   95.006062][    T1] Modules linked in:
> [   95.009815][    T1] CPU: 25 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc3-next-20190806+ #11
> [   95.018161][    T1] Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
> [   95.028593][    T1] pstate: 60400009 (nZCv daif +PAN -UAO)
> [   95.034077][    T1] pc : device_links_supplier_sync_state_resume+0x100/0x128
> [   95.041124][    T1] lr : device_links_supplier_sync_state_resume+0x100/0x128
> [   95.048167][    T1] sp : 34ff800806e6fbc0
> [   95.052172][    T1] x29: 34ff800806e6fc00 x28: 0000000000000000
> [   95.058177][    T1] x27: 0000000000000000 x26: 0000000000000000
> [   95.064181][    T1] x25: 0000000000000038 x24: 0000000000000000
> [   95.070185][    T1] x23: 0000000000000000 x22: 0000000000000019
> [   95.076189][    T1] x21: 0000000000000000 x20: f9ff808b804e6c50
> [   95.082193][    T1] x19: ffff100014a6e600 x18: 0000000000000040
> [   95.088197][    T1] x17: 0000000000000000 x16: 86ff80099d581b50
> [   95.094201][    T1] x15: 0000000000000000 x14: ffff100010086d1c
> [   95.100205][    T1] x13: ffff1000109d8688 x12: ffffffffffffffff
> [   95.106209][    T1] x11: 00000000000000f9 x10: ffff0808b804e6c6
> [   95.112213][    T1] x9 : 4b71ad522c851d00 x8 : 4b71ad522c851d00
> [   95.118217][    T1] x7 : 6170206574617473 x6 : ffff100014076972
> [   95.124221][    T1] x5 : 34ff800806e6f8f0 x4 : 000000000000000f
> [   95.130225][    T1] x3 : ffff1000101bfa5c x2 : 0000000000000001
> [   95.136229][    T1] x1 : 0000000000000001 x0 : 0000000000000022
> [   95.142233][    T1] Call trace:
> [   95.145374][    T1]  device_links_supplier_sync_state_resume+0x100/0x128
> [   95.152074][    T1]  of_platform_sync_state_init+0x10/0x1c
> [   95.157557][    T1]  do_one_initcall+0x2f8/0x600
> [   95.162172][    T1]  do_initcall_level+0x37c/0x3fc
> [   95.166959][    T1]  do_basic_setup+0x34/0x4c
> [   95.171313][    T1]  kernel_init_freeable+0x188/0x24c
> [   95.176363][    T1]  kernel_init+0x18/0x334
> [   95.180543][    T1]  ret_from_fork+0x10/0x18
> [   95.184809][    T1] ---[ end trace a9ea68c902540fe5 ]---
> [   95.269085][    T1] Freeing unused kernel memory: 28672K
> [  101.069860][    T1] Checked W+X mappings: passed, no W+X pages found
> [  101.076265][    T1] Run /init as init process
> [  101.186359][    T1] systemd[1]: System time before build time, advancing clock.


I tested it again on my device (on an older kernel) and I don't see
this warning. Is this on an ARM64 target without a populated DT?
That's the only thing I can see that could cause this warning.

This is literally the code with the matching pause/resume. I can't
think of any other way the pause/resume could have ended up not
matching.

static int __init of_platform_default_populate_init(void)
{
        struct device_node *node;

        if (!of_have_populated_dt())
                return -ENODEV;

        platform_bus_type.add_links = of_link_to_suppliers;
        device_links_supplier_sync_state_pause(); <=========== PAUSE
        /*
         * Handle certain compatibles explicitly, since we don't want to create
         * platform_devices for every node in /reserved-memory with a
         * "compatible",
         */
        for_each_matching_node(node, reserved_mem_matches)
                of_platform_device_create(node, NULL, NULL);

        node = of_find_node_by_path("/firmware");
        if (node) {
                of_platform_populate(node, NULL, NULL, NULL);
                of_node_put(node);
        }

        /* Populate everything else. */
        of_platform_default_populate(NULL, NULL, NULL);

        return 0;
}
arch_initcall_sync(of_platform_default_populate_init);

static int __init of_platform_sync_state_init(void)
{
        device_links_supplier_sync_state_resume(); <========= RESUME
        return 0;
}
late_initcall_sync(of_platform_sync_state_init);

Thanks,
Saravana

^ permalink raw reply

* Re: [PATCH v3 2/5] ASoC: fsl_sai: Update Tx/Rx channel enable mask
From: Nicolin Chen @ 2019-08-07  1:17 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: broonie, l.stach, mihai.serban, alsa-devel, timur, shengjiu.wang,
	angus, tiwai, linux-imx, kernel, festevam, linux-kernel,
	devicetree, robh
In-Reply-To: <20190806151214.6783-3-daniel.baluta@nxp.com>

On Tue, Aug 06, 2019 at 06:12:11PM +0300, Daniel Baluta wrote:
> Tx channel enable (TCE) / Rx channel enable (RCE) bits
> enable corresponding data channel for Tx/Rx operation.
> 
> Because SAI supports up the 8 channels TCE/RCE occupy
> up the 8 bits inside TCR3/RCR3 registers we need to extend
> the mask to reflect this.
> 
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>

Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>

Thanks

> ---
>  sound/soc/fsl/fsl_sai.c | 6 ++++--
>  sound/soc/fsl/fsl_sai.h | 1 +
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 17b0aff4ee8b..637b1d12a575 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -599,7 +599,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
>  	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
>  	int ret;
>  
> -	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
> +	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx),
> +			   FSL_SAI_CR3_TRCE_MASK,
>  			   FSL_SAI_CR3_TRCE);
>  
>  	ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
> @@ -614,7 +615,8 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
>  	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
>  	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
>  
> -	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
> +	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx),
> +			   FSL_SAI_CR3_TRCE_MASK, 0);
>  }
>  
>  static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
> diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
> index 4bb478041d67..20c5b9b1e8bc 100644
> --- a/sound/soc/fsl/fsl_sai.h
> +++ b/sound/soc/fsl/fsl_sai.h
> @@ -110,6 +110,7 @@
>  
>  /* SAI Transmit and Receive Configuration 3 Register */
>  #define FSL_SAI_CR3_TRCE	BIT(16)
> +#define FSL_SAI_CR3_TRCE_MASK	GENMASK(23, 16)
>  #define FSL_SAI_CR3_WDFL(x)	(x)
>  #define FSL_SAI_CR3_WDFL_MASK	0x1f
>  
> -- 
> 2.17.1
> 

^ permalink raw reply

* Re: [PATCH v3 1/5] ASoC: fsl_sai: Add registers definition for multiple datalines
From: Nicolin Chen @ 2019-08-07  1:16 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: broonie, l.stach, mihai.serban, alsa-devel, timur, shengjiu.wang,
	angus, tiwai, linux-imx, kernel, festevam, linux-kernel,
	devicetree, robh
In-Reply-To: <20190806151214.6783-2-daniel.baluta@nxp.com>

On Tue, Aug 06, 2019 at 06:12:10PM +0300, Daniel Baluta wrote:
> SAI IP supports up to 8 data lines. The configuration of
> supported number of data lines is decided at SoC integration
> time.
> 
> This patch adds definitions for all related data TX/RX registers:
> 	* TDR0..7, Transmit data register
> 	* TFR0..7, Transmit FIFO register
> 	* RDR0..7, Receive data register
> 	* RFR0..7, Receive FIFO register
> 
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>

Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>

Thanks

> ---
>  sound/soc/fsl/fsl_sai.c | 76 +++++++++++++++++++++++++++++++++++------
>  sound/soc/fsl/fsl_sai.h | 36 ++++++++++++++++---
>  2 files changed, 98 insertions(+), 14 deletions(-)
> 
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 6d3c6c8d50ce..17b0aff4ee8b 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -685,7 +685,14 @@ static struct reg_default fsl_sai_reg_defaults[] = {
>  	{FSL_SAI_TCR3, 0},
>  	{FSL_SAI_TCR4, 0},
>  	{FSL_SAI_TCR5, 0},
> -	{FSL_SAI_TDR,  0},
> +	{FSL_SAI_TDR0, 0},
> +	{FSL_SAI_TDR1, 0},
> +	{FSL_SAI_TDR2, 0},
> +	{FSL_SAI_TDR3, 0},
> +	{FSL_SAI_TDR4, 0},
> +	{FSL_SAI_TDR5, 0},
> +	{FSL_SAI_TDR6, 0},
> +	{FSL_SAI_TDR7, 0},
>  	{FSL_SAI_TMR,  0},
>  	{FSL_SAI_RCR1, 0},
>  	{FSL_SAI_RCR2, 0},
> @@ -704,7 +711,14 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
>  	case FSL_SAI_TCR3:
>  	case FSL_SAI_TCR4:
>  	case FSL_SAI_TCR5:
> -	case FSL_SAI_TFR:
> +	case FSL_SAI_TFR0:
> +	case FSL_SAI_TFR1:
> +	case FSL_SAI_TFR2:
> +	case FSL_SAI_TFR3:
> +	case FSL_SAI_TFR4:
> +	case FSL_SAI_TFR5:
> +	case FSL_SAI_TFR6:
> +	case FSL_SAI_TFR7:
>  	case FSL_SAI_TMR:
>  	case FSL_SAI_RCSR:
>  	case FSL_SAI_RCR1:
> @@ -712,8 +726,22 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
>  	case FSL_SAI_RCR3:
>  	case FSL_SAI_RCR4:
>  	case FSL_SAI_RCR5:
> -	case FSL_SAI_RDR:
> -	case FSL_SAI_RFR:
> +	case FSL_SAI_RDR0:
> +	case FSL_SAI_RDR1:
> +	case FSL_SAI_RDR2:
> +	case FSL_SAI_RDR3:
> +	case FSL_SAI_RDR4:
> +	case FSL_SAI_RDR5:
> +	case FSL_SAI_RDR6:
> +	case FSL_SAI_RDR7:
> +	case FSL_SAI_RFR0:
> +	case FSL_SAI_RFR1:
> +	case FSL_SAI_RFR2:
> +	case FSL_SAI_RFR3:
> +	case FSL_SAI_RFR4:
> +	case FSL_SAI_RFR5:
> +	case FSL_SAI_RFR6:
> +	case FSL_SAI_RFR7:
>  	case FSL_SAI_RMR:
>  		return true;
>  	default:
> @@ -726,9 +754,30 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
>  	switch (reg) {
>  	case FSL_SAI_TCSR:
>  	case FSL_SAI_RCSR:
> -	case FSL_SAI_TFR:
> -	case FSL_SAI_RFR:
> -	case FSL_SAI_RDR:
> +	case FSL_SAI_TFR0:
> +	case FSL_SAI_TFR1:
> +	case FSL_SAI_TFR2:
> +	case FSL_SAI_TFR3:
> +	case FSL_SAI_TFR4:
> +	case FSL_SAI_TFR5:
> +	case FSL_SAI_TFR6:
> +	case FSL_SAI_TFR7:
> +	case FSL_SAI_RFR0:
> +	case FSL_SAI_RFR1:
> +	case FSL_SAI_RFR2:
> +	case FSL_SAI_RFR3:
> +	case FSL_SAI_RFR4:
> +	case FSL_SAI_RFR5:
> +	case FSL_SAI_RFR6:
> +	case FSL_SAI_RFR7:
> +	case FSL_SAI_RDR0:
> +	case FSL_SAI_RDR1:
> +	case FSL_SAI_RDR2:
> +	case FSL_SAI_RDR3:
> +	case FSL_SAI_RDR4:
> +	case FSL_SAI_RDR5:
> +	case FSL_SAI_RDR6:
> +	case FSL_SAI_RDR7:
>  		return true;
>  	default:
>  		return false;
> @@ -744,7 +793,14 @@ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
>  	case FSL_SAI_TCR3:
>  	case FSL_SAI_TCR4:
>  	case FSL_SAI_TCR5:
> -	case FSL_SAI_TDR:
> +	case FSL_SAI_TDR0:
> +	case FSL_SAI_TDR1:
> +	case FSL_SAI_TDR2:
> +	case FSL_SAI_TDR3:
> +	case FSL_SAI_TDR4:
> +	case FSL_SAI_TDR5:
> +	case FSL_SAI_TDR6:
> +	case FSL_SAI_TDR7:
>  	case FSL_SAI_TMR:
>  	case FSL_SAI_RCSR:
>  	case FSL_SAI_RCR1:
> @@ -885,8 +941,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
>  				   MCLK_DIR(index));
>  	}
>  
> -	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
> -	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
> +	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
> +	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
>  	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
>  	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
>  
> diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
> index 7c1ef671da28..4bb478041d67 100644
> --- a/sound/soc/fsl/fsl_sai.h
> +++ b/sound/soc/fsl/fsl_sai.h
> @@ -20,8 +20,22 @@
>  #define FSL_SAI_TCR3	0x0c /* SAI Transmit Configuration 3 */
>  #define FSL_SAI_TCR4	0x10 /* SAI Transmit Configuration 4 */
>  #define FSL_SAI_TCR5	0x14 /* SAI Transmit Configuration 5 */
> -#define FSL_SAI_TDR	0x20 /* SAI Transmit Data */
> -#define FSL_SAI_TFR	0x40 /* SAI Transmit FIFO */
> +#define FSL_SAI_TDR0	0x20 /* SAI Transmit Data 0 */
> +#define FSL_SAI_TDR1	0x24 /* SAI Transmit Data 1 */
> +#define FSL_SAI_TDR2	0x28 /* SAI Transmit Data 2 */
> +#define FSL_SAI_TDR3	0x2C /* SAI Transmit Data 3 */
> +#define FSL_SAI_TDR4	0x30 /* SAI Transmit Data 4 */
> +#define FSL_SAI_TDR5	0x34 /* SAI Transmit Data 5 */
> +#define FSL_SAI_TDR6	0x38 /* SAI Transmit Data 6 */
> +#define FSL_SAI_TDR7	0x3C /* SAI Transmit Data 7 */
> +#define FSL_SAI_TFR0	0x40 /* SAI Transmit FIFO 0 */
> +#define FSL_SAI_TFR1	0x44 /* SAI Transmit FIFO 1 */
> +#define FSL_SAI_TFR2	0x48 /* SAI Transmit FIFO 2 */
> +#define FSL_SAI_TFR3	0x4C /* SAI Transmit FIFO 3 */
> +#define FSL_SAI_TFR4	0x50 /* SAI Transmit FIFO 4 */
> +#define FSL_SAI_TFR5	0x54 /* SAI Transmit FIFO 5 */
> +#define FSL_SAI_TFR6	0x58 /* SAI Transmit FIFO 6 */
> +#define FSL_SAI_TFR7	0x5C /* SAI Transmit FIFO 7 */
>  #define FSL_SAI_TMR	0x60 /* SAI Transmit Mask */
>  #define FSL_SAI_RCSR	0x80 /* SAI Receive Control */
>  #define FSL_SAI_RCR1	0x84 /* SAI Receive Configuration 1 */
> @@ -29,8 +43,22 @@
>  #define FSL_SAI_RCR3	0x8c /* SAI Receive Configuration 3 */
>  #define FSL_SAI_RCR4	0x90 /* SAI Receive Configuration 4 */
>  #define FSL_SAI_RCR5	0x94 /* SAI Receive Configuration 5 */
> -#define FSL_SAI_RDR	0xa0 /* SAI Receive Data */
> -#define FSL_SAI_RFR	0xc0 /* SAI Receive FIFO */
> +#define FSL_SAI_RDR0	0xa0 /* SAI Receive Data 0 */
> +#define FSL_SAI_RDR1	0xa4 /* SAI Receive Data 1 */
> +#define FSL_SAI_RDR2	0xa8 /* SAI Receive Data 2 */
> +#define FSL_SAI_RDR3	0xac /* SAI Receive Data 3 */
> +#define FSL_SAI_RDR4	0xb0 /* SAI Receive Data 4 */
> +#define FSL_SAI_RDR5	0xb4 /* SAI Receive Data 5 */
> +#define FSL_SAI_RDR6	0xb8 /* SAI Receive Data 6 */
> +#define FSL_SAI_RDR7	0xbc /* SAI Receive Data 7 */
> +#define FSL_SAI_RFR0	0xc0 /* SAI Receive FIFO 0 */
> +#define FSL_SAI_RFR1	0xc4 /* SAI Receive FIFO 1 */
> +#define FSL_SAI_RFR2	0xc8 /* SAI Receive FIFO 2 */
> +#define FSL_SAI_RFR3	0xcc /* SAI Receive FIFO 3 */
> +#define FSL_SAI_RFR4	0xd0 /* SAI Receive FIFO 4 */
> +#define FSL_SAI_RFR5	0xd4 /* SAI Receive FIFO 5 */
> +#define FSL_SAI_RFR6	0xd8 /* SAI Receive FIFO 6 */
> +#define FSL_SAI_RFR7	0xdc /* SAI Receive FIFO 7 */
>  #define FSL_SAI_RMR	0xe0 /* SAI Receive Mask */
>  
>  #define FSL_SAI_xCSR(tx)	(tx ? FSL_SAI_TCSR : FSL_SAI_RCSR)
> -- 
> 2.17.1
> 

^ permalink raw reply

* Re: [PATCH v2 3/7] ASoC: fsl_sai: Add support to enable multiple data lines
From: Nicolin Chen @ 2019-08-07  1:14 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Daniel Baluta, Mark Brown, Lucas Stach, Mihai Serban, Linux-ALSA,
	Viorel Suman, Timur Tabi, S.j. Wang, Angus Ainslie (Purism),
	Takashi Iwai, dl-linux-imx, Pengutronix Kernel Team,
	Fabio Estevam, Linux Kernel Mailing List, Devicetree List,
	Rob Herring
In-Reply-To: <CAEnQRZBN5Y+75cpgS2h3LwDj5BkF5cesqu6=V3GuPU4=5pgn6A@mail.gmail.com>

On Tue, Aug 06, 2019 at 06:23:27PM +0300, Daniel Baluta wrote:
> On Mon, Jul 29, 2019 at 11:22 PM Nicolin Chen <nicoleotsuka@gmail.com> wrote:
> >
> > On Sun, Jul 28, 2019 at 10:24:25PM +0300, Daniel Baluta wrote:
> > > SAI supports up to 8 Rx/Tx data lines which can be enabled
> > > using TCE/RCE bits of TCR3/RCR3 registers.
> > >
> > > Data lines to be enabled are read from DT fsl,dl-mask property.
> > > By default (if no DT entry is provided) only data line 0 is enabled.
> > >
> > > Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
> > > ---
> > >  sound/soc/fsl/fsl_sai.c | 11 ++++++++++-
> > >  sound/soc/fsl/fsl_sai.h |  4 +++-
> > >  2 files changed, 13 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> > > index 637b1d12a575..5e7cb7fd29f5 100644
> > > --- a/sound/soc/fsl/fsl_sai.c
> > > +++ b/sound/soc/fsl/fsl_sai.c
> > > @@ -601,7 +601,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
> > >
> > >       regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx),
> > >                          FSL_SAI_CR3_TRCE_MASK,
> > > -                        FSL_SAI_CR3_TRCE);
> > > +                        FSL_SAI_CR3_TRCE(sai->soc_data->dl_mask[tx]);
> > >
> > >       ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
> > >                       SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints);
> > > @@ -888,6 +888,15 @@ static int fsl_sai_probe(struct platform_device *pdev)
> > >               }
> > >       }
> > >
> > > +     /*
> > > +      * active data lines mask for TX/RX, defaults to 1 (only the first
> > > +      * data line is enabled
> > > +      */
> > > +     sai->dl_mask[RX] = 1;
> > > +     sai->dl_mask[TX] = 1;
> > > +     of_property_read_u32_index(np, "fsl,dl-mask", RX, &sai->dl_mask[RX]);
> > > +     of_property_read_u32_index(np, "fsl,dl-mask", TX, &sai->dl_mask[TX]);
> >
> > Just curious what if we enable 8 data lines through DT bindings
> > while an audio file only has 1 or 2 channels. Will TRCE bits be
> > okay to stay with 8 data channels configurations? Btw, how does
> > DMA work for the data registers? ESAI has one entry at a fixed
> > address for all data channels while SAI seems to have different
> > data registers.
> 
> Hi Nicolin,
> 
> I have sent v3 and removed this patch from the series because we
> need to find a better solution.

Ack. I was in that private mail thread. So it's totally fine.

> 
> I think we should enable TCE based on the number of available datalines
> and the number of active channels.  Will come with a RFC patch later.

Yea, that's exactly what I suspected during patch review and
what I suggested previously too. Look forward to your patch.

> Pasting here the reply of SAI Audio IP owner regarding to your question above,
> just for anyone to have more info of our private discussion:
> 
> If all 8 datalines are enabled using TCE then the transmit FIFO for
> all 8 datalines need to be serviced, otherwise a FIFO underrun will be
> generated.
> Each dataline has a separate transmit FIFO with a separate register to
> service the FIFO, so each dataline can be serviced separately. Note
> that configuring FCOMB=2 would make it look like ESAI with a common
> address for all FIFOs.
> When performing DMA transfers to multiple datalines, there are a
> couple of options:
>     * Use 1 DMA channel to copy first slot for each dataline to each
> FIFO and then update the destination address back to the first
> register.
>     * Configure separate DMA channel for each dataline and trigger the
> first one by the DMA request and the subsequent channels by DMA
> linking or scatter/gather.
>     * Configure FCOMB=2 and treat it the same as the ESAI. This is
> almost the same as 1, but don’t need to update the destination
> address.
> 
> Thanks,
> Daniel.

^ permalink raw reply

* Re: [PATCH v3 3/5] RISC-V: Fix unsupported isa string info.
From: Atish Patra @ 2019-08-07  1:13 UTC (permalink / raw)
  To: paul.walmsley@sifive.com
  Cc: info@metux.net, allison@lohutok.net, palmer@sifive.com,
	aou@eecs.berkeley.edu, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, tglx@linutronix.de,
	daniel.lezcano@linaro.org, Anup Patel, mark.rutland@arm.com,
	robh+dt@kernel.org, johan@kernel.org, tiny.windzz@gmail.com,
	gregkh@linuxfoundation.org, gary@garyguo.net,
	linux-riscv@lists.infradead.org
In-Reply-To: <alpine.DEB.2.21.9999.1908061625190.13971@viisi.sifive.com>

On Tue, 2019-08-06 at 16:27 -0700, Paul Walmsley wrote:
> On Wed, 31 Jul 2019, Atish Patra wrote:
> 
> > Currently, kernel prints a info warning if any of the extensions
> > from "mafdcsu" is missing in device tree. This is not entirely
> > correct as Linux can boot with "f or d" extensions if kernel is
> > configured accordingly. Moreover, it will continue to print the
> > info string for future extensions such as hypervisor as well which
> > is misleading. /proc/cpuinfo also doesn't print any other
> > extensions
> > except "mafdcsu".
> > 
> > Make sure that info log is only printed only if kernel is
> > configured
> > to have any mandatory extensions but device tree doesn't describe
> > it.
> > All the extensions present in device tree and follow the order
> > described in the RISC-V specification (except 'S') are printed via
> > /proc/cpuinfo always.
> > 
> > Signed-off-by: Atish Patra <atish.patra@wdc.com>
> 
> I tested this patch after dropping the CONFIG_ISA_RISCV_C test (see 
> below).  Running "cat /proc/cpuinfo" generated the following kernel 
> warnings:
>           
> [   73.412626] unsupported ISA extensions "su" in device tree for cpu
> [0]
> [   73.418417] unsupported ISA extensions "su" in device tree for cpu
> [1]
> [   73.424912] unsupported ISA extensions "su" in device tree for cpu
> [2]
> [   73.431425] unsupported ISA extensions "su" in device tree for cpu
> [3]
> 

yeah. I just tested in QEMU. It seems that QEMU has 
"rv64imafdcsu" as isa string in its DT. That's why I never saw this.

> Seems like the "su" should be dropped from mandatory_ext.  What do
> you 
> think?
> 

Yup. As DT binding only mention imafdc, mandatory extensions should
contain only that and just consider "su" extensions are considered as
implicit as we are running Linux. 

Do you think QEMU DT should be updated to reflect that ?

> > ---
> >  arch/riscv/kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++-----
> > ----
> >  1 file changed, 37 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> > index 7da3c6a93abd..9b1d4550fbe6 100644
> > --- a/arch/riscv/kernel/cpu.c
> > +++ b/arch/riscv/kernel/cpu.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/seq_file.h>
> >  #include <linux/of.h>
> >  #include <asm/smp.h>
> > +#include <asm/hwcap.h>
> >  
> >  /*
> >   * Returns the hart ID of the given device tree node, or -ENODEV
> > if the node
> > @@ -46,11 +47,14 @@ int riscv_of_processor_hartid(struct
> > device_node *node)
> >  
> >  #ifdef CONFIG_PROC_FS
> >  
> > -static void print_isa(struct seq_file *f, const char *orig_isa)
> > +static void print_isa(struct seq_file *f, const char *orig_isa,
> > +		      unsigned long cpuid)
> >  {
> > -	static const char *ext = "mafdcsu";
> > +	static const char *mandatory_ext = "mafdcsu";
> >  	const char *isa = orig_isa;
> >  	const char *e;
> > +	char unsupported_isa[26] = {0};
> > +	int index = 0;
> >  
> >  	/*
> >  	 * Linux doesn't support rv32e or rv128i, and we only support
> > booting
> > @@ -70,27 +74,50 @@ static void print_isa(struct seq_file *f, const
> > char *orig_isa)
> >  	isa += 5;
> >  
> >  	/*
> > -	 * Check the rest of the ISA string for valid extensions,
> > printing those
> > -	 * we find.  RISC-V ISA strings define an order, so we only
> > print the
> > +	 * RISC-V ISA strings define an order, so we only print all the
> >  	 * extension bits when they're in order. Hide the supervisor
> > (S)
> >  	 * extension from userspace as it's not accessible from there.
> > +	 * Throw a warning only if any mandatory extensions are not
> > available
> > +	 * and kernel is configured to have that mandatory extensions.
> >  	 */
> > -	for (e = ext; *e != '\0'; ++e) {
> > -		if (isa[0] == e[0]) {
> > +	for (e = mandatory_ext; *e != '\0'; ++e) {
> > +		if (isa[0] != e[0]) {
> > +#if defined(CONFIG_ISA_RISCV_C)
> 
> There's no Kconfig option by this name, and we're requiring
> compressed 

Sorry. This was a typo. It should have been CONFIG_RISCV_ISA_C.

> instruction support as part of the RISC-V Linux baseline.  Could you
> share 
> the rationale behind this?  

I think I added this check at the config file. Looking at the Kconfig,
RISCV_ISA_C is always enabled. So we can drop this.

Regards,
Atish
> Looks to me like this should be dropped.
> 
> 
> > +			if (isa[0] == 'c')
> > +				continue;
> > +#endif
> > +#if defined(CONFIG_FP)
> > +			if ((isa[0] == 'f') || (isa[0] == 'd'))
> > +				continue;
> > +#endif
> > +			unsupported_isa[index] = e[0];
> > +			index++;
> > +		}
> > +		/* Only write if part of isa string */
> > +		if (isa[0] != '\0') {
> >  			if (isa[0] != 's')
> >  				seq_write(f, isa, 1);
> > -
> >  			isa++;
> >  		}
> >  	}
> > +	if (isa[0] != '\0') {
> > +		/* Add remainging isa strings */
> > +		for (e = isa; *e != '\0'; ++e) {
> > +#if !defined(CONFIG_VIRTUALIZATION)
> > +			if (e[0] != 'h')
> > +#endif
> > +				seq_write(f, e, 1);
> > +		}
> > +	}
> >  	seq_puts(f, "\n");
> >  
> >  	/*
> >  	 * If we were given an unsupported ISA in the device tree then
> > print
> >  	 * a bit of info describing what went wrong.
> >  	 */
> > -	if (isa[0] != '\0')
> > -		pr_info("unsupported ISA \"%s\" in device tree\n",
> > orig_isa);
> > +	if (unsupported_isa[0])
> > +		pr_info("unsupported ISA extensions \"%s\" in device
> > tree for cpu [%ld]\n",
> > +			unsupported_isa, cpuid);
> >  }
> >  
> >  static void print_mmu(struct seq_file *f, const char *mmu_type)
> > @@ -134,7 +161,7 @@ static int c_show(struct seq_file *m, void *v)
> >  	seq_printf(m, "processor\t: %lu\n", cpu_id);
> >  	seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
> >  	if (!of_property_read_string(node, "riscv,isa", &isa))
> > -		print_isa(m, isa);
> > +		print_isa(m, isa, cpu_id);
> >  	if (!of_property_read_string(node, "mmu-type", &mmu))
> >  		print_mmu(m, mmu);
> >  	if (!of_property_read_string(node, "compatible", &compat)
> > -- 
> > 2.21.0
> > 
> > 
> 
> - Paul


^ permalink raw reply

* Re: [alsa-devel] [PATCH v2 1/7] ASoC: fsl_sai: Add registers definition for multiple datalines
From: Nicolin Chen @ 2019-08-07  1:12 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: Mark Brown, Daniel Baluta, Devicetree List, Linux-ALSA,
	Pengutronix Kernel Team, Timur Tabi, Rob Herring, S.j. Wang,
	Angus Ainslie (Purism), Takashi Iwai, Linux Kernel Mailing List,
	dl-linux-imx, Viorel Suman, Fabio Estevam, Mihai Serban,
	Lucas Stach
In-Reply-To: <CAEnQRZBpQPoi5OH--c=ubKYc6B3rspmVnb846UTFW7P5SE62ww@mail.gmail.com>

On Tue, Aug 06, 2019 at 02:15:03PM +0300, Daniel Baluta wrote:
> On Tue, Jul 30, 2019 at 10:59 AM Nicolin Chen <nicoleotsuka@gmail.com> wrote:
> >
> > On Mon, Jul 29, 2019 at 09:20:01PM +0100, Mark Brown wrote:
> > > On Mon, Jul 29, 2019 at 10:57:43PM +0300, Daniel Baluta wrote:
> > > > On Mon, Jul 29, 2019 at 10:42 PM Nicolin Chen <nicoleotsuka@gmail.com> wrote:
> > > > > On Sun, Jul 28, 2019 at 10:24:23PM +0300, Daniel Baluta wrote:
> > >
> > > > > > @@ -704,7 +711,14 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
> > > > > >       case FSL_SAI_TCR3:
> > > > > >       case FSL_SAI_TCR4:
> > > > > >       case FSL_SAI_TCR5:
> > > > > > -     case FSL_SAI_TFR:
> > > > > > +     case FSL_SAI_TFR0:
> > >
> > > > > A tricky thing here is that those SAI instances on older SoC don't
> > > > > support multi data lines physically, while seemly having registers
> > > > > pre-defined. So your change doesn't sound doing anything wrong to
> > > > > them at all, I am still wondering if it is necessary to apply them
> > > > > to newer compatible only though, as for older compatibles of SAI,
> > > > > these registers would be useless and confusing if being exposed.
> > >
> > > > > What do you think?
> > >
> > > > Yes, I thought about this too. But, I tried to keep the code as short
> > > > as possible and technically it is not wrong. When 1 data line is supported
> > > > for example application will only care about TDR0, TFR0, etc.
> > >
> > > So long as it's safe to read the registers (you don't get a bus error or
> > > anything) I'd say it's more trouble than it's worth to have separate
> > > regmap configuations just for this.  The main reasons for restricting
> > > readability are where there's physical problems with doing the reads or
> > > to keep the size of the debugfs files under control for usability and
> > > performance reasons.
> >
> > Thanks for the input, Mark.
> >
> > Daniel, did you get a chance to test it on older SoCs? At least
> > nothing breaks like bus errors?
> 
> Tested on imx6sx-sdb, everything looks good. No bus errors.

Okay. Let's just stick to it then. Thanks for the reply.

^ permalink raw reply

* "of/platform: Pause/resume sync state during init and of_platform_populate()" with a warning on arm64
From: Qian Cai @ 2019-08-07  0:46 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Greg Kroah-Hartman, Rob Herring, Linux List Kernel Mailing,
	linux-arm-kernel, devicetree

It looks like the linux-next commit “of/platform: Pause/resume sync state during init and of_platform_populate()” [1]
Introduced a warning while booting arm64.

[1] https://lore.kernel.org/lkml/20190731221721.187713-6-saravanak@google.com/

[   93.449300][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
[   93.464873][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for cmdq
[   93.485481][    T1] arm-smmu-v3 arm-smmu-v3.4.auto: allocated 524288 entries for evtq
[   93.496320][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: option mask 0x2
[   93.502917][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: ias 44-bit, oas 44-bit (features 0x0000170d)
[   93.621818][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for cmdq
[   93.643000][    T1] arm-smmu-v3 arm-smmu-v3.5.auto: allocated 524288 entries for evtq
[   94.519445][    T1] libphy: Fixed MDIO Bus: probed
[   94.524649][    T1] EFI Variables Facility v0.08 2004-May-17
[   94.601166][    T1] NET: Registered protocol family 17
[   94.766008][    T1] zswap: loaded using pool lzo/zbud
[   94.774745][    T1] kmemleak: Kernel memory leak detector initialized (mempool size: 16384)
[   94.774756][ T1699] kmemleak: Automatic memory scanning thread started
[   94.812338][ T1368] pcieport 0000:0f:00.0: Adding to iommu group 0
[   94.984466][    T1] ------------[ cut here ]------------
[   94.989827][    T1] Unmatched sync_state pause/resume!
[   94.989894][    T1] WARNING: CPU: 25 PID: 1 at drivers/base/core.c:691 device_links_supplier_sync_state_resume+0x100/0x128
[   95.006062][    T1] Modules linked in:
[   95.009815][    T1] CPU: 25 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc3-next-20190806+ #11
[   95.018161][    T1] Hardware name: HPE Apollo 70             /C01_APACHE_MB         , BIOS L50_5.13_1.11 06/18/2019
[   95.028593][    T1] pstate: 60400009 (nZCv daif +PAN -UAO)
[   95.034077][    T1] pc : device_links_supplier_sync_state_resume+0x100/0x128
[   95.041124][    T1] lr : device_links_supplier_sync_state_resume+0x100/0x128
[   95.048167][    T1] sp : 34ff800806e6fbc0
[   95.052172][    T1] x29: 34ff800806e6fc00 x28: 0000000000000000 
[   95.058177][    T1] x27: 0000000000000000 x26: 0000000000000000 
[   95.064181][    T1] x25: 0000000000000038 x24: 0000000000000000 
[   95.070185][    T1] x23: 0000000000000000 x22: 0000000000000019 
[   95.076189][    T1] x21: 0000000000000000 x20: f9ff808b804e6c50 
[   95.082193][    T1] x19: ffff100014a6e600 x18: 0000000000000040 
[   95.088197][    T1] x17: 0000000000000000 x16: 86ff80099d581b50 
[   95.094201][    T1] x15: 0000000000000000 x14: ffff100010086d1c 
[   95.100205][    T1] x13: ffff1000109d8688 x12: ffffffffffffffff 
[   95.106209][    T1] x11: 00000000000000f9 x10: ffff0808b804e6c6 
[   95.112213][    T1] x9 : 4b71ad522c851d00 x8 : 4b71ad522c851d00 
[   95.118217][    T1] x7 : 6170206574617473 x6 : ffff100014076972 
[   95.124221][    T1] x5 : 34ff800806e6f8f0 x4 : 000000000000000f 
[   95.130225][    T1] x3 : ffff1000101bfa5c x2 : 0000000000000001 
[   95.136229][    T1] x1 : 0000000000000001 x0 : 0000000000000022 
[   95.142233][    T1] Call trace:
[   95.145374][    T1]  device_links_supplier_sync_state_resume+0x100/0x128
[   95.152074][    T1]  of_platform_sync_state_init+0x10/0x1c
[   95.157557][    T1]  do_one_initcall+0x2f8/0x600
[   95.162172][    T1]  do_initcall_level+0x37c/0x3fc
[   95.166959][    T1]  do_basic_setup+0x34/0x4c
[   95.171313][    T1]  kernel_init_freeable+0x188/0x24c
[   95.176363][    T1]  kernel_init+0x18/0x334
[   95.180543][    T1]  ret_from_fork+0x10/0x18
[   95.184809][    T1] ---[ end trace a9ea68c902540fe5 ]---
[   95.269085][    T1] Freeing unused kernel memory: 28672K
[  101.069860][    T1] Checked W+X mappings: passed, no W+X pages found
[  101.076265][    T1] Run /init as init process
[  101.186359][    T1] systemd[1]: System time before build time, advancing clock.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v5 2/2] mmc: Add support for the ASPEED SD controller
From: Andrew Jeffery @ 2019-08-07  0:36 UTC (permalink / raw)
  To: linux-mmc
  Cc: Andrew Jeffery, ulf.hansson, robh+dt, mark.rutland, joel,
	adrian.hunter, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, ryanchen.aspeed
In-Reply-To: <20190807003629.2974-1-andrew@aj.id.au>

Add a minimal driver for ASPEED's SD controller, which exposes two
SDHCIs.

The ASPEED design implements a common register set for the SDHCIs, and
moves some of the standard configuration elements out to this common
area (e.g. 8-bit mode, and card detect configuration which is not
currently supported).

The SD controller has a dedicated hardware interrupt that is shared
between the slots. The common register set exposes information on which
slot triggered the interrupt; early revisions of the patch introduced an
irqchip for the register, but reality is it doesn't behave as an
irqchip, and the result fits awkwardly into the irqchip APIs. Instead
I've taken the simple approach of using the IRQ as a shared IRQ with
some minor performance impact for the second slot.

Ryan was the original author of the patch - I've taken his work and
massaged it to drop the irqchip support and rework the devicetree
integration. The driver has been smoke tested under qemu against a
minimal SD controller model and lightly tested on an ast2500-evb.

Signed-off-by: Ryan Chen <ryanchen.aspeed@gmail.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>

---

v5:
* Cleanup sdhci driver on registration failure

v4: No change

v2:
* Add AST2600 compatible
* Drop SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN
* Ensure slot number is valid
* Fix build with CONFIG_MODULES
* Fix module license string
* Non-PCI devices won't die
* Rename aspeed_sdc_configure_8bit_mode()
* Rename aspeed_sdhci_pdata
* Switch to sdhci_enable_clk()
* Use PTR_ERR() on the right `struct platform_device *`
---
 drivers/mmc/host/Kconfig           |  12 ++
 drivers/mmc/host/Makefile          |   1 +
 drivers/mmc/host/sdhci-of-aspeed.c | 332 +++++++++++++++++++++++++++++
 3 files changed, 345 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-of-aspeed.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 14d89a108edd..0f8a230de2f3 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -154,6 +154,18 @@ config MMC_SDHCI_OF_ARASAN
 
 	  If unsure, say N.
 
+config MMC_SDHCI_OF_ASPEED
+	tristate "SDHCI OF support for the ASPEED SDHCI controller"
+	depends on MMC_SDHCI_PLTFM
+	depends on OF
+	help
+	  This selects the ASPEED Secure Digital Host Controller Interface.
+
+	  If you have a controller with this interface, say Y or M here. You
+	  also need to enable an appropriate bus interface.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_OF_AT91
 	tristate "SDHCI OF support for the Atmel SDMMC controller"
 	depends on MMC_SDHCI_PLTFM
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 73578718f119..390ee162fe71 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX)	+= sdhci-esdhc-imx.o
 obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ARASAN)	+= sdhci-of-arasan.o
+obj-$(CONFIG_MMC_SDHCI_OF_ASPEED)	+= sdhci-of-aspeed.o
 obj-$(CONFIG_MMC_SDHCI_OF_AT91)		+= sdhci-of-at91.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
new file mode 100644
index 000000000000..8bb095ca2fa9
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (C) 2019 ASPEED Technology Inc. */
+/* Copyright (C) 2019 IBM Corp. */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include "sdhci-pltfm.h"
+
+#define ASPEED_SDC_INFO		0x00
+#define   ASPEED_SDC_S1MMC8	BIT(25)
+#define   ASPEED_SDC_S0MMC8	BIT(24)
+
+struct aspeed_sdc {
+	struct clk *clk;
+	struct resource *res;
+
+	spinlock_t lock;
+	void __iomem *regs;
+};
+
+struct aspeed_sdhci {
+	struct aspeed_sdc *parent;
+	u32 width_mask;
+};
+
+static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc,
+					   struct aspeed_sdhci *sdhci,
+					   bool bus8)
+{
+	u32 info;
+
+	/* Set/clear 8 bit mode */
+	spin_lock(&sdc->lock);
+	info = readl(sdc->regs + ASPEED_SDC_INFO);
+	if (bus8)
+		info |= sdhci->width_mask;
+	else
+		info &= ~sdhci->width_mask;
+	writel(info, sdc->regs + ASPEED_SDC_INFO);
+	spin_unlock(&sdc->lock);
+}
+
+static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	int div;
+	u16 clk;
+
+	if (clock == host->clock)
+		return;
+
+	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+	if (clock == 0)
+		goto out;
+
+	for (div = 1; div < 256; div *= 2) {
+		if ((host->max_clk / div) <= clock)
+			break;
+	}
+	div >>= 1;
+
+	clk = div << SDHCI_DIVIDER_SHIFT;
+
+	sdhci_enable_clk(host, clk);
+
+out:
+	host->clock = clock;
+}
+
+static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width)
+{
+	struct sdhci_pltfm_host *pltfm_priv;
+	struct aspeed_sdhci *aspeed_sdhci;
+	struct aspeed_sdc *aspeed_sdc;
+	u8 ctrl;
+
+	pltfm_priv = sdhci_priv(host);
+	aspeed_sdhci = sdhci_pltfm_priv(pltfm_priv);
+	aspeed_sdc = aspeed_sdhci->parent;
+
+	/* Set/clear 8-bit mode */
+	aspeed_sdc_configure_8bit_mode(aspeed_sdc, aspeed_sdhci,
+				       width == MMC_BUS_WIDTH_8);
+
+	/* Set/clear 1 or 4 bit mode */
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+	if (width == MMC_BUS_WIDTH_4)
+		ctrl |= SDHCI_CTRL_4BITBUS;
+	else
+		ctrl &= ~SDHCI_CTRL_4BITBUS;
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+}
+
+static const struct sdhci_ops aspeed_sdhci_ops = {
+	.set_clock = aspeed_sdhci_set_clock,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.set_bus_width = aspeed_sdhci_set_bus_width,
+	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
+	.reset = sdhci_reset,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+static const struct sdhci_pltfm_data aspeed_sdhci_pdata = {
+	.ops = &aspeed_sdhci_ops,
+	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+};
+
+static inline int aspeed_sdhci_calculate_slot(struct aspeed_sdhci *dev,
+					      struct resource *res)
+{
+	resource_size_t delta;
+
+	if (!res || resource_type(res) != IORESOURCE_MEM)
+		return -EINVAL;
+
+	if (res->start < dev->parent->res->start)
+		return -EINVAL;
+
+	delta = res->start - dev->parent->res->start;
+	if (delta & (0x100 - 1))
+		return -EINVAL;
+
+	return (delta / 0x100) - 1;
+}
+
+static int aspeed_sdhci_probe(struct platform_device *pdev)
+{
+	struct sdhci_pltfm_host *pltfm_host;
+	struct aspeed_sdhci *dev;
+	struct sdhci_host *host;
+	struct resource *res;
+	int slot;
+	int ret;
+
+	host = sdhci_pltfm_init(pdev, &aspeed_sdhci_pdata, sizeof(*dev));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	pltfm_host = sdhci_priv(host);
+	dev = sdhci_pltfm_priv(pltfm_host);
+	dev->parent = dev_get_drvdata(pdev->dev.parent);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	slot = aspeed_sdhci_calculate_slot(dev, res);
+
+	if (slot < 0)
+		return slot;
+	else if (slot >= 2)
+		return -EINVAL;
+
+	dev_info(&pdev->dev, "Configuring for slot %d\n", slot);
+	dev->width_mask = !slot ? ASPEED_SDC_S0MMC8 : ASPEED_SDC_S1MMC8;
+
+	sdhci_get_of_property(pdev);
+
+	pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pltfm_host->clk))
+		return PTR_ERR(pltfm_host->clk);
+
+	ret = clk_prepare_enable(pltfm_host->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable SDIO clock\n");
+		goto err_pltfm_free;
+	}
+
+	ret = mmc_of_parse(host->mmc);
+	if (ret)
+		goto err_sdhci_add;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_sdhci_add;
+
+	return 0;
+
+err_sdhci_add:
+	clk_disable_unprepare(pltfm_host->clk);
+err_pltfm_free:
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int aspeed_sdhci_remove(struct platform_device *pdev)
+{
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_host *host;
+	int dead = 0;
+
+	host = platform_get_drvdata(pdev);
+	pltfm_host = sdhci_priv(host);
+
+	sdhci_remove_host(host, dead);
+
+	clk_disable_unprepare(pltfm_host->clk);
+
+	sdhci_pltfm_free(pdev);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_sdhci_of_match[] = {
+	{ .compatible = "aspeed,ast2400-sdhci", },
+	{ .compatible = "aspeed,ast2500-sdhci", },
+	{ .compatible = "aspeed,ast2600-sdhci", },
+	{ }
+};
+
+static struct platform_driver aspeed_sdhci_driver = {
+	.driver		= {
+		.name	= "sdhci-aspeed",
+		.of_match_table = aspeed_sdhci_of_match,
+	},
+	.probe		= aspeed_sdhci_probe,
+	.remove		= aspeed_sdhci_remove,
+};
+
+static int aspeed_sdc_probe(struct platform_device *pdev)
+
+{
+	struct device_node *parent, *child;
+	struct aspeed_sdc *sdc;
+	int ret;
+
+	sdc = devm_kzalloc(&pdev->dev, sizeof(*sdc), GFP_KERNEL);
+	if (!sdc)
+		return -ENOMEM;
+
+	spin_lock_init(&sdc->lock);
+
+	sdc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(sdc->clk))
+		return PTR_ERR(sdc->clk);
+
+	ret = clk_prepare_enable(sdc->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to enable SDCLK\n");
+		return ret;
+	}
+
+	sdc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sdc->regs = devm_ioremap_resource(&pdev->dev, sdc->res);
+	if (IS_ERR(sdc->regs)) {
+		ret = PTR_ERR(sdc->regs);
+		goto err_clk;
+	}
+
+	dev_set_drvdata(&pdev->dev, sdc);
+
+	parent = pdev->dev.of_node;
+	for_each_available_child_of_node(parent, child) {
+		struct platform_device *cpdev;
+
+		cpdev = of_platform_device_create(child, NULL, &pdev->dev);
+		if (IS_ERR(cpdev)) {
+			of_node_put(child);
+			ret = PTR_ERR(cpdev);
+			goto err_clk;
+		}
+	}
+
+	return 0;
+
+err_clk:
+	clk_disable_unprepare(sdc->clk);
+	return ret;
+}
+
+static int aspeed_sdc_remove(struct platform_device *pdev)
+{
+	struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
+
+	clk_disable_unprepare(sdc->clk);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_sdc_of_match[] = {
+	{ .compatible = "aspeed,ast2400-sd-controller", },
+	{ .compatible = "aspeed,ast2500-sd-controller", },
+	{ .compatible = "aspeed,ast2600-sd-controller", },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, aspeed_sdc_of_match);
+
+static struct platform_driver aspeed_sdc_driver = {
+	.driver		= {
+		.name	= "sd-controller-aspeed",
+		.pm	= &sdhci_pltfm_pmops,
+		.of_match_table = aspeed_sdc_of_match,
+	},
+	.probe		= aspeed_sdc_probe,
+	.remove		= aspeed_sdc_remove,
+};
+
+static int __init aspeed_sdc_init(void)
+{
+	int rc;
+
+	rc = platform_driver_register(&aspeed_sdhci_driver);
+	if (rc < 0)
+		return rc;
+
+	rc = platform_driver_register(&aspeed_sdc_driver);
+	if (rc < 0)
+		platform_driver_unregister(&aspeed_sdhci_driver);
+
+	return rc;
+}
+module_init(aspeed_sdc_init);
+
+static void __exit aspeed_sdc_exit(void)
+{
+	platform_driver_unregister(&aspeed_sdc_driver);
+	platform_driver_unregister(&aspeed_sdhci_driver);
+}
+module_exit(aspeed_sdc_exit);
+
+MODULE_DESCRIPTION("Driver for the ASPEED SD/SDIO/SDHCI Controllers");
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
+MODULE_LICENSE("GPL");
-- 
2.20.1

^ permalink raw reply related

* [PATCH v5 1/2] dt-bindings: mmc: Document Aspeed SD controller
From: Andrew Jeffery @ 2019-08-07  0:36 UTC (permalink / raw)
  To: linux-mmc
  Cc: Andrew Jeffery, ulf.hansson, robh+dt, mark.rutland, joel,
	adrian.hunter, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, ryanchen.aspeed
In-Reply-To: <20190807003629.2974-1-andrew@aj.id.au>

The ASPEED SD/SDIO/MMC controller exposes two slots implementing the
SDIO Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit
data bus if only a single slot is enabled.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

---
v4:
* Make use of mmc-controller.yaml
* Document sdhci,auto-cmd12

v2:
* Fix compatible enums
* Add AST2600 compatibles
* Describe #address-cells / #size-cells
---
 .../devicetree/bindings/mmc/aspeed,sdhci.yaml | 105 ++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml

diff --git a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
new file mode 100644
index 000000000000..570f8c72662b
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/aspeed,sdhci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED SD/SDIO/MMC Controller
+
+maintainers:
+  - Andrew Jeffery <andrew@aj.id.au>
+  - Ryan Chen <ryanchen.aspeed@gmail.com>
+
+description: |+
+  The ASPEED SD/SDIO/eMMC controller exposes two slots implementing the SDIO
+  Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit data bus if
+  only a single slot is enabled.
+
+  The two slots are supported by a common configuration area. As the SDHCIs for
+  the slots are dependent on the common configuration area, they are described
+  as child nodes.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-sd-controller
+      - aspeed,ast2500-sd-controller
+      - aspeed,ast2600-sd-controller
+  reg:
+    maxItems: 1
+    description: Common configuration registers
+  "#address-cells":
+    const: 1
+  "#size-cells":
+    const: 1
+  ranges: true
+  clocks:
+    maxItems: 1
+    description: The SD/SDIO controller clock gate
+
+patternProperties:
+  "^sdhci@[0-9a-f]+$":
+    type: object
+    allOf:
+        - $ref: mmc-controller.yaml
+    properties:
+      compatible:
+        enum:
+          - aspeed,ast2400-sdhci
+          - aspeed,ast2500-sdhci
+          - aspeed,ast2600-sdhci
+      reg:
+        maxItems: 1
+        description: The SDHCI registers
+      clocks:
+        maxItems: 1
+        description: The SD bus clock
+      interrupts:
+        maxItems: 1
+        description: The SD interrupt shared between both slots
+      sdhci,auto-cmd12:
+        type: boolean
+        description: Specifies that controller should use auto CMD12
+    required:
+      - compatible
+      - reg
+      - clocks
+      - interrupts
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+  - clocks
+
+examples:
+  - |
+    #include <dt-bindings/clock/aspeed-clock.h>
+    sdc@1e740000 {
+            compatible = "aspeed,ast2500-sd-controller";
+            reg = <0x1e740000 0x100>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            ranges = <0 0x1e740000 0x10000>;
+            clocks = <&syscon ASPEED_CLK_GATE_SDCLK>;
+
+            sdhci0: sdhci@100 {
+                    compatible = "aspeed,ast2500-sdhci";
+                    reg = <0x100 0x100>;
+                    interrupts = <26>;
+                    sdhci,auto-cmd12;
+                    clocks = <&syscon ASPEED_CLK_SDIO>;
+            };
+
+            sdhci1: sdhci@200 {
+                    compatible = "aspeed,ast2500-sdhci";
+                    reg = <0x200 0x100>;
+                    interrupts = <26>;
+                    sdhci,auto-cmd12;
+                    clocks = <&syscon ASPEED_CLK_SDIO>;
+            };
+    };
-- 
2.20.1

^ permalink raw reply related

* [PATCH v5 0/2] mmc: Add support for the ASPEED SD controller
From: Andrew Jeffery @ 2019-08-07  0:36 UTC (permalink / raw)
  To: linux-mmc
  Cc: Andrew Jeffery, ulf.hansson, robh+dt, mark.rutland, joel,
	adrian.hunter, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, ryanchen.aspeed

Hello,

v5 of the ASPEED SDHCI patches fixes an error-path cleanup issue pointed out by
Adrian.

v4 can be found here:

http://patchwork.ozlabs.org/cover/1141949/

Please review!

Andrew

Andrew Jeffery (2):
  dt-bindings: mmc: Document Aspeed SD controller
  mmc: Add support for the ASPEED SD controller

 .../devicetree/bindings/mmc/aspeed,sdhci.yaml | 105 ++++++
 drivers/mmc/host/Kconfig                      |  12 +
 drivers/mmc/host/Makefile                     |   1 +
 drivers/mmc/host/sdhci-of-aspeed.c            | 332 ++++++++++++++++++
 4 files changed, 450 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml
 create mode 100644 drivers/mmc/host/sdhci-of-aspeed.c

-- 
2.20.1

^ permalink raw reply

* Re: [PATCH v3 3/5] RISC-V: Fix unsupported isa string info.
From: Paul Walmsley @ 2019-08-06 23:27 UTC (permalink / raw)
  To: Atish Patra
  Cc: Mark Rutland, devicetree, Anup Patel, Yangtao Li,
	Greg Kroah-Hartman, Daniel Lezcano, linux-kernel, Rob Herring,
	Johan Hovold, Albert Ou, Palmer Dabbelt, Gary Guo, linux-riscv,
	Enrico Weigelt, Thomas Gleixner, Allison Randal
In-Reply-To: <20190801005843.10343-4-atish.patra@wdc.com>

On Wed, 31 Jul 2019, Atish Patra wrote:

> Currently, kernel prints a info warning if any of the extensions
> from "mafdcsu" is missing in device tree. This is not entirely
> correct as Linux can boot with "f or d" extensions if kernel is
> configured accordingly. Moreover, it will continue to print the
> info string for future extensions such as hypervisor as well which
> is misleading. /proc/cpuinfo also doesn't print any other extensions
> except "mafdcsu".
> 
> Make sure that info log is only printed only if kernel is configured
> to have any mandatory extensions but device tree doesn't describe it.
> All the extensions present in device tree and follow the order
> described in the RISC-V specification (except 'S') are printed via
> /proc/cpuinfo always.
> 
> Signed-off-by: Atish Patra <atish.patra@wdc.com>

I tested this patch after dropping the CONFIG_ISA_RISCV_C test (see 
below).  Running "cat /proc/cpuinfo" generated the following kernel 
warnings:
          
[   73.412626] unsupported ISA extensions "su" in device tree for cpu [0]
[   73.418417] unsupported ISA extensions "su" in device tree for cpu [1]
[   73.424912] unsupported ISA extensions "su" in device tree for cpu [2]
[   73.431425] unsupported ISA extensions "su" in device tree for cpu [3]

Seems like the "su" should be dropped from mandatory_ext.  What do you 
think?

> ---
>  arch/riscv/kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++---------
>  1 file changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 7da3c6a93abd..9b1d4550fbe6 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -7,6 +7,7 @@
>  #include <linux/seq_file.h>
>  #include <linux/of.h>
>  #include <asm/smp.h>
> +#include <asm/hwcap.h>
>  
>  /*
>   * Returns the hart ID of the given device tree node, or -ENODEV if the node
> @@ -46,11 +47,14 @@ int riscv_of_processor_hartid(struct device_node *node)
>  
>  #ifdef CONFIG_PROC_FS
>  
> -static void print_isa(struct seq_file *f, const char *orig_isa)
> +static void print_isa(struct seq_file *f, const char *orig_isa,
> +		      unsigned long cpuid)
>  {
> -	static const char *ext = "mafdcsu";
> +	static const char *mandatory_ext = "mafdcsu";
>  	const char *isa = orig_isa;
>  	const char *e;
> +	char unsupported_isa[26] = {0};
> +	int index = 0;
>  
>  	/*
>  	 * Linux doesn't support rv32e or rv128i, and we only support booting
> @@ -70,27 +74,50 @@ static void print_isa(struct seq_file *f, const char *orig_isa)
>  	isa += 5;
>  
>  	/*
> -	 * Check the rest of the ISA string for valid extensions, printing those
> -	 * we find.  RISC-V ISA strings define an order, so we only print the
> +	 * RISC-V ISA strings define an order, so we only print all the
>  	 * extension bits when they're in order. Hide the supervisor (S)
>  	 * extension from userspace as it's not accessible from there.
> +	 * Throw a warning only if any mandatory extensions are not available
> +	 * and kernel is configured to have that mandatory extensions.
>  	 */
> -	for (e = ext; *e != '\0'; ++e) {
> -		if (isa[0] == e[0]) {
> +	for (e = mandatory_ext; *e != '\0'; ++e) {
> +		if (isa[0] != e[0]) {
> +#if defined(CONFIG_ISA_RISCV_C)

There's no Kconfig option by this name, and we're requiring compressed 
instruction support as part of the RISC-V Linux baseline.  Could you share 
the rationale behind this?  Looks to me like this should be dropped.


> +			if (isa[0] == 'c')
> +				continue;
> +#endif
> +#if defined(CONFIG_FP)
> +			if ((isa[0] == 'f') || (isa[0] == 'd'))
> +				continue;
> +#endif
> +			unsupported_isa[index] = e[0];
> +			index++;
> +		}
> +		/* Only write if part of isa string */
> +		if (isa[0] != '\0') {
>  			if (isa[0] != 's')
>  				seq_write(f, isa, 1);
> -
>  			isa++;
>  		}
>  	}
> +	if (isa[0] != '\0') {
> +		/* Add remainging isa strings */
> +		for (e = isa; *e != '\0'; ++e) {
> +#if !defined(CONFIG_VIRTUALIZATION)
> +			if (e[0] != 'h')
> +#endif
> +				seq_write(f, e, 1);
> +		}
> +	}
>  	seq_puts(f, "\n");
>  
>  	/*
>  	 * If we were given an unsupported ISA in the device tree then print
>  	 * a bit of info describing what went wrong.
>  	 */
> -	if (isa[0] != '\0')
> -		pr_info("unsupported ISA \"%s\" in device tree\n", orig_isa);
> +	if (unsupported_isa[0])
> +		pr_info("unsupported ISA extensions \"%s\" in device tree for cpu [%ld]\n",
> +			unsupported_isa, cpuid);
>  }
>  
>  static void print_mmu(struct seq_file *f, const char *mmu_type)
> @@ -134,7 +161,7 @@ static int c_show(struct seq_file *m, void *v)
>  	seq_printf(m, "processor\t: %lu\n", cpu_id);
>  	seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
>  	if (!of_property_read_string(node, "riscv,isa", &isa))
> -		print_isa(m, isa);
> +		print_isa(m, isa, cpu_id);
>  	if (!of_property_read_string(node, "mmu-type", &mmu))
>  		print_mmu(m, mmu);
>  	if (!of_property_read_string(node, "compatible", &compat)
> -- 
> 2.21.0
> 
> 


- Paul

^ permalink raw reply

* Re: [PATCH v1 2/2] net: npcm: add NPCM7xx EMC 10/100 Ethernet driver
From: Willem de Bruijn @ 2019-08-06 22:51 UTC (permalink / raw)
  To: Avi Fishman
  Cc: Patrick Venture, Nancy Yuen, Benjamin Fair, David Miller,
	Rob Herring, Mark Rutland, Greg Kroah-Hartman, Tomer Maimon,
	Tali Perry, OpenBMC Maillist, Network Development, devicetree,
	linux-kernel, Thomas Gleixner
In-Reply-To: <CAKKbWA6hjxupFQNnTUOfeKLXd2wtZ9+g7uUpe34CeErn5kBAaA@mail.gmail.com>

> > Does this device support stacked VLAN?
> I am not familiar with stacked VLAN.
> Our HW for sure there is no support. can the SW stack handle it for me?
> Does it mean that  the packets can be larger?

If the device does not support it, I believe it's fine to leave it to S/W.

> > Is this really the device maximum?
>
> The device can support upto 64KB, but of course I will not allocate
> for each RX data such a big buffer.
> Can I know what is the maximum value the network stack may request? I
> saw many driver allocating 1536 for each packet.

The maximum is the minimum of the link layer and device h/w limits,
but you indeed don't want to allocate for worst case if that is highly
unlikely.

Your choice of 1500 is fine for this initial commit, really. More on
MTU below with ndo_change_mtu

> > > +       rxd_offset = (readl((ether->reg + REG_CRXDSA)) -
> > > +                     readl((ether->reg + REG_RXDLSA)))
> > > +               / sizeof(struct npcm7xx_txbd);
> > > +       DUMP_PRINT("RXD offset    %6d\n", rxd_offset);
> > > +       DUMP_PRINT("cur_rx        %6d\n", ether->cur_rx);
> > > +       DUMP_PRINT("rx_err        %6d\n", ether->rx_err);
> > > +       ether->rx_err = 0;
> > > +       DUMP_PRINT("rx_berr       %6d\n", ether->rx_berr);
> > > +       ether->rx_berr = 0;
> > > +       DUMP_PRINT("rx_stuck      %6d\n", ether->rx_stuck);
> > > +       ether->rx_stuck = 0;
> > > +       DUMP_PRINT("rdu           %6d\n", ether->rdu);
> > > +       ether->rdu = 0;
> > > +       DUMP_PRINT("rxov rx       %6d\n", ether->rxov);
> > > +       ether->rxov = 0;
> > > +       /* debug counters */
> > > +       DUMP_PRINT("rx_int_count  %6d\n", ether->rx_int_count);
> > > +       ether->rx_int_count = 0;
> > > +       DUMP_PRINT("rx_err_count  %6d\n", ether->rx_err_count);
> > > +       ether->rx_err_count = 0;
> >
> > Basic counters like tx_packets and rx_errors are probably better
> > exported regardless of debug level as net_device_stats. And then don't
> > need to be copied in debug output.
>
> They are also exported there, see below ether->stats.tx_packets++; and
> ether->stats.rx_errors++;
> those are different counters for debug since we had HW issues that we
> needed to workaround and might need them for future use.
> Currently the driver is stable on millions of parts in the field.
>
> >
> > Less standard counters like tx interrupt count are probably better
> > candidates for ethtool -S.
>
> I don't have support for ethtool.
> is it a must? it is quite some work and this driver is already in the
> field for quite some years.

Your driver includes a struct ethtool_ops. Implementing its callback
.get_ethtool_stats seems straightforward?

David also requested using standard infrastructure over this custom
debug logic. Ethool stats appear the most logical choice to me. But
there may be others.

> > > +static struct sk_buff *get_new_skb(struct net_device *netdev, u32 i)
> > > +{
> > > +       __le32 buffer;
> > > +       struct npcm7xx_ether *ether = netdev_priv(netdev);
> > > +       struct sk_buff *skb = netdev_alloc_skb(netdev,
> > > +               roundup(MAX_PACKET_SIZE_W_CRC, 4));
> > > +
> > > +       if (unlikely(!skb)) {
> > > +               if (net_ratelimit())
> > > +                       netdev_warn(netdev, "failed to allocate rx skb\n");
> >
> > can use net_warn_ratelimited (here and elsewhere)
>
> should I replace every netdev_warn/err/info with net_warn/err/inf_ratelimited?
> I saw in drivers that are using net_warn_ratelimited, that many time
> uses also netdev_warn/err/info

They probably use the second in non-ratelimited cases?

> > > +static irqreturn_t npcm7xx_tx_interrupt(int irq, void *dev_id)
> > > +{
> > > +       struct npcm7xx_ether *ether;
> > > +       struct platform_device *pdev;
> > > +       struct net_device *netdev;
> > > +       __le32 status;
> > > +       unsigned long flags;
> > > +
> > > +       netdev = dev_id;
> > > +       ether = netdev_priv(netdev);
> > > +       pdev = ether->pdev;
> > > +
> > > +       npcm7xx_get_and_clear_int(netdev, &status, 0xFFFF0000);
> > > +
> > > +       ether->tx_int_count++;
> > > +
> > > +       if (status & MISTA_EXDEF)
> > > +               dev_err(&pdev->dev, "emc defer exceed interrupt status=0x%08X\n"
> > > +                       , status);
> > > +       else if (status & MISTA_TXBERR) {
> > > +               dev_err(&pdev->dev, "emc bus error interrupt status=0x%08X\n",
> > > +                       status);
> > > +#ifdef CONFIG_NPCM7XX_EMC_ETH_DEBUG
> > > +               npcm7xx_info_print(netdev);
> > > +#endif
> > > +               spin_lock_irqsave(&ether->lock, flags);
> >
> > irqsave in hard interrupt context?
>
> I need to protect my REG_MIEN register that is changed in other places.
> I think that spin_lock_irqsave() is relevant when working in SMP,
> since other CPU may still be running.
> Isn't it?

This is an interesting case. The hardware interrupt handler will not
interrupt itself. But it is architecture dependent whether all
interrupts are disabled when a particular interrupt handler is running
(as per the unreliable guide to locking).

So even in absence of SMP, this would indeed need spin_lock_irqsave if
there are multiple hardware interrupt handlers potentially accessing
the same data. That sounds unlikely in general, but does happen here
for REG_MIEN, in npcm7xx_tx_interrupt and npcm7xx_rx_interrupt. So I
was mistaken, this is not only the most conservative locking method,
it is indeed required.

>
> >
> > > +               writel(0, (ether->reg + REG_MIEN)); /* disable any interrupt */
> > > +               spin_unlock_irqrestore(&ether->lock, flags);
> > > +               ether->need_reset = 1;
> > > +       } else if (status & ~(MISTA_TXINTR | MISTA_TXCP | MISTA_TDU))
> > > +               dev_err(&pdev->dev, "emc other error interrupt status=0x%08X\n",
> > > +                       status);
> > > +
> > > +    /* if we got MISTA_TXCP | MISTA_TDU remove those interrupt and call napi */
> >
> > The goal of napi is to keep interrupts disabled until napi completes.
>
> We have a HW issue that because of it I still enabled TX complete interrupt,
> I will see if I can disable all interrupts and only leave the error interrupts

Please do. I'm not sure what happens when trying to schedule napi
while it is already scheduled or running. Even in the best case
(nothing), these spurious interrupts are inefficient.

> >
> > > +       if (status & (MISTA_TXCP | MISTA_TDU) &
> > > +           readl((ether->reg + REG_MIEN))) {
> > > +               __le32 reg_mien;
> > > +
> > > +               spin_lock_irqsave(&ether->lock, flags);
> > > +               reg_mien = readl((ether->reg + REG_MIEN));
> > > +               if (reg_mien & ENTDU)
> > > +                       /* Disable TDU interrupt */
> > > +                       writel(reg_mien & (~ENTDU), (ether->reg + REG_MIEN));
> > > +
> > > +               spin_unlock_irqrestore(&ether->lock, flags);
> > > +
> > > +               if (status & MISTA_TXCP)
> > > +                       ether->tx_cp_i++;
> > > +               if (status & MISTA_TDU)
> > > +                       ether->tx_tdu_i++;
> > > +       } else {
> > > +               dev_dbg(&pdev->dev, "status=0x%08X\n", status);
> > > +       }
> > > +
> > > +       napi_schedule(&ether->napi);
> > > +
> > > +       return IRQ_HANDLED;
> > > +}
> > > +
> > > +static irqreturn_t npcm7xx_rx_interrupt(int irq, void *dev_id)
> > > +{
> > > +       struct net_device *netdev = (struct net_device *)dev_id;
> > > +       struct npcm7xx_ether *ether = netdev_priv(netdev);
> > > +       struct platform_device *pdev = ether->pdev;
> > > +       __le32 status;
> > > +       unsigned long flags;
> > > +       unsigned int any_err = 0;
> > > +       __le32 rxfsm;
> > > +
> > > +       npcm7xx_get_and_clear_int(netdev, &status, 0xFFFF);
> >
> > Same here
>
> in non error case I do leave only the error interrupts and schedule napi.

Oh, so the Rx interrupt remains suppressed. Then that's fine.

> > > +static const struct net_device_ops npcm7xx_ether_netdev_ops = {
> > > +       .ndo_open               = npcm7xx_ether_open,
> > > +       .ndo_stop               = npcm7xx_ether_close,
> > > +       .ndo_start_xmit         = npcm7xx_ether_start_xmit,
> > > +       .ndo_get_stats          = npcm7xx_ether_stats,
> > > +       .ndo_set_rx_mode        = npcm7xx_ether_set_rx_mode,
> > > +       .ndo_set_mac_address    = npcm7xx_set_mac_address,
> > > +       .ndo_do_ioctl           = npcm7xx_ether_ioctl,
> > > +       .ndo_validate_addr      = eth_validate_addr,
> > > +       .ndo_change_mtu         = eth_change_mtu,
> >
> > This is marked as deprecated. Also in light of the hardcoded
> > MAX_PACKET_SIZE, probably want to set dev->max_mtu.
>
> can I just not set .ndo_change_mtu? or I must add my own implementation?
> setting of dev->max_mtu, can be done in probe, yes?

It's fine to just not have it. The patchset that introduced max_mtu
(61e84623ace3, a52ad514fdf3) removed many.

One reason to have a callback function is to bring the device down/up
with different sized rx buffers.

But handling that might be too much extra complexity for the initial
patch. It's fine to keep the fixed rx alloc size as is.

> BTW, I see that currently the mtu is 1500 but I do get transactions
> with len of 1514 (I didn't compile with VLAN)

That is to be expected, as MTU excludes link layer header (and FCS,
and perhaps also vlan?)

^ permalink raw reply

* Re: [PATCH 0/3] Add basic support for RTC on Allwinner H6 SoC
From: Ondřej Jirman @ 2019-08-06 22:27 UTC (permalink / raw)
  To: Chen-Yu Tsai, Mark Rutland, Alessandro Zummo, Alexandre Belloni,
	devicetree, Maxime Ripard, linux-kernel, linux-sunxi, Rob Herring,
	linux-arm-kernel, linux-rtc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20190806183045.edhm3qzpegscf2z7-9v8tmBix7cb9zxVx7UNMDg@public.gmane.org>

On Tue, Aug 06, 2019 at 08:30:45PM +0200, megous hlavni wrote:
> On Mon, Apr 15, 2019 at 04:18:12PM +0800, Chen-Yu Tsai wrote:
> > On Fri, Apr 12, 2019 at 8:07 PM megous via linux-sunxi
> > <linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org> wrote:
> > >
> > > From: Ondrej Jirman <megous-5qf/QAjKc83QT0dZR+AlfA@public.gmane.org>
> > >
> > > I went through the datasheets for H6 and H5, and compared the differences.
> > > RTCs are largely similar, but not entirely compatible. Incompatibilities
> > > are in details not yet implemented by the rtc driver though.
> > >
> > > I also corrected the clock tree in H6 DTSI.
> > 
> > Please also add DCXO clock input/output and XO clock input to the bindings
> > and DT, and also fix up the clock tree. You can skip them in the driver for
> > now, but please add a TODO. As long as you don't change the clock-output-name
> > of osc24M, everything should work as before.
> > 
> > We just want the DT to describe what is actually there. For the XO input,
> > you could just directly reference the external crystal node. The gate for
> > it is likely somewhere in the PRCM block, which we don't have docs for.
> 
> So I was thinking about this for a while, and came up with this:
> 
> ----------------- arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -----------------
> index 64c39f663d22..ac99ddbebe5c 100644
> @@ -627,14 +635,15 @@
> 
>  		rtc: rtc@7000000 {
>  			compatible = "allwinner,sun50i-h6-rtc";
>  			reg = <0x07000000 0x400>;
>  			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
>  				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> -			clock-output-names = "osc32k", "osc32k-out", "iosc";
> -			clocks = <&ext_osc32k>;
> +			clock-output-names = "osc32k", "osc32k-out", "iosc", "hosc";
> +			clock-names = "losc", "dcxo";
> +			clocks = <&ext_osc32k>, <&osc24M>;
>  			#clock-cells = <1>;
>  		};
> 
>  		r_ccu: clock@7010000 {
>  			compatible = "allwinner,sun50i-h6-r-ccu";
>  			reg = <0x07010000 0x400>;
> 
> I'm not completely sure how (or why?) to describe in DTSI which oscillator the
> designer used (XO vs DCXO). This information is signalled by the pad voltage and
> can be determined at runtime from DCXO_CTRL_REG's OSC_CLK_SRC_SEL (bit 3). It's
> not possible to change at runtime.
> 
> HOSC source selection is only material to the CPUS (ARISC) firmware when it
> wants to turn off all PLLs and the main crystal oscillator so that it knows
> which one to turn off. I don't see any other use for it. It's just
> informational. I don't think (future) crust firmware has space to be reading
> DTBs, so the detection will be using OSC_CLK_SRC_SEL anyway.
> 
> Maybe whether XO or DCXO is used also matters if you want to do some fine
> tunning of DCXO (control register has pletny of options), but that's probably
> better done in u-boot. And there's still no need to read HOSC source from DT.
> The driver can just check compatible, and if it is H6 and OSC_CLK_SRC_SEL is 1,
> it can do it's DCXO tunning, or whatever. But neither OS nor bootloader will
> be using this info to gate/disable the osciallator.
> 
> If we really want this in DT, maybe we can model it by having just two input
> clocks to RTC described in DTSI, and the DTSI for H6 would have this by default:
> 
> 	clock-names = "losc", "dcxo";
> 	clocks = <&ext_osc32k>, <&osc24M>;
> 
> And the board designer could change it from a board file, like this:
> 
> &rtc {
> 	clock-names = "losc", "xo";
> 	clocks = <&ext_osc32k>, <&osc24M>;
> };
> 
> The driver could decide which oscillator is used by the presence of either
> dcxo or xo input clock.
> 
> But in any case, the driver can also get this info from DCXO_CTRL_REG's
> OSC_CLK_SRC_SEL, so it doesn't need to read this from DT at all. So it's a bit
> pointless.
> 
> So I see two options:
> 
> 1) skip adding dcxo/xo to input clocks of RTC completely
> 2) the above
> 
> What do you think?

I tried option 2) and it feels pointless. It just creates this clock tree:

osc24M
  hosc
    plls...

from:

osc24M
  plls...

and doesn't achieve anything else, other than complicating things, for no reason
because no driver will ever need or use this info from the DT.

So my preference is for keeping it simple and going with option 1).

regards,
	o.


> regards,
> 	o.
> 
> 
> > > There's a small detail here, that's not described absolutely correctly in
> > > DTSI, but the difference is not really that material. ext_osc32k is
> > > originally modelled as a fixed clock that feeds into RTC module, but in
> > > reality it's the RTC module that implements via its registers enabling and
> > > disabling of this oscillator/clock.
> > >
> > > Though:
> > > - there's no other possible user of ext_osc32k than RTC module
> > > - there's no other possible external configuration for the crystal
> > >   circuit that would need to be handled in the dts per board
> > >
> > > So I guess, while the description is not perfect, this patch series still
> > > improves the current situation. Or maybe I'm misunderstanding something,
> > > and &ext_osc32k node just describes a fact that there's a crystal on
> > > the board. Then, everything is perhaps fine. :)
> > 
> > Correct. The external clock nodes are modeling the crystal, not the internal
> > clock gate / distributor.
> > 
> > Were the vendor to not include the crystal (for whatever reasons), the DT
> > should be able to describe it via the absence of the clock input, and the
> > driver should correctly use the internal (inaccurate) oscillator. I realize
> > the clocks property is required, and the driver doesn't handle this case
> > either, so we might have to fix that if it were to appear in the wild.
> > 
> > > For now, the enable bit for this oscillator is toggled by the re-parenting
> > > code automatically, as needed.
> > 
> > That's fine. No need to increase the clock tree depth.
> > 
> > ChenYu
> > 
> > > This patchset is necessary for implementing the WiFi/Bluetooth support
> > > on boards using H6 SoC.
> > >
> > > Please take a look.
> > >
> > > Thank you and regards,
> > >   Ondrej Jirman
> > >
> > > Ondrej Jirman (3):
> > >   dt-bindings: Add compatible for H6 RTC
> > >   rtc: sun6i: Add support for H6 RTC
> > >   arm64: dts: sun50i-h6: Add support for RTC and fix the clock tree
> > >
> > >  .../devicetree/bindings/rtc/sun6i-rtc.txt     |  1 +
> > >  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 30 +++++++-------
> > >  drivers/rtc/rtc-sun6i.c                       | 40 ++++++++++++++++++-
> > >  3 files changed, 55 insertions(+), 16 deletions(-)
> > >
> > > --
> > > 2.21.0
> > >
> > > --
> > > You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> > > To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> > > For more options, visit https://groups.google.com/d/optout.
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 2/2] of/platform: Disable generic device linking code for PowerPC
From: Saravana Kannan @ 2019-08-06 22:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: Greg Kroah-Hartman, Frank Rowand, Stephen Rothwell,
	Android Kernel Team,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel@vger.kernel.org
In-Reply-To: <CAL_Jsq+BwHSj1XUNp_eY362XnNoOqVTNHqAkvnbgece8ZQE3Qw@mail.gmail.com>

On Tue, Aug 6, 2019 at 2:27 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Tue, Aug 6, 2019 at 1:27 PM Saravana Kannan <saravanak@google.com> wrote:
> >
> > PowerPC platforms don't use the generic of/platform code to populate the
> > devices from DT.
>
> Yes, they do.

No they don't. My wording could be better, but they don't use
of_platform_default_populate_init()
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/of/platform.c#n511

>
> > Therefore the generic device linking code is never used
> > in PowerPC.  Compile it out to avoid warning about unused functions.
>
> I'd prefer this get disabled on PPC using 'if (IS_ENABLED(CONFIG_PPC))
> return' rather than #ifdefs.

I'm just moving the existing ifndef some lines above. I don't want to
go change existing #ifndef in this patch. Maybe that should be a
separate patch series that goes and fixes all such code in drivers/of/
or driver/

-Saravana

>
> >
> > If a specific PowerPC platform wants to use this code in the future,
> > bringing this back for PowerPC would be trivial. We'll just need to export
> > of_link_to_suppliers() and then let the machine specific files do the
> > linking as they populate the devices from DT.
> >
> > Signed-off-by: Saravana Kannan <saravanak@google.com>
> > ---
> >  drivers/of/platform.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> > index f68de5c4aeff..a2a4e4b79d43 100644
> > --- a/drivers/of/platform.c
> > +++ b/drivers/of/platform.c
> > @@ -506,6 +506,7 @@ int of_platform_default_populate(struct device_node *root,
> >  }
> >  EXPORT_SYMBOL_GPL(of_platform_default_populate);
> >
> > +#ifndef CONFIG_PPC
> >  static bool of_link_is_valid(struct device_node *con, struct device_node *sup)
> >  {
> >         of_node_get(sup);
> > @@ -683,7 +684,6 @@ static int of_link_to_suppliers(struct device *dev)
> >         return __of_link_to_suppliers(dev, dev->of_node);
> >  }
> >
> > -#ifndef CONFIG_PPC
> >  static const struct of_device_id reserved_mem_matches[] = {
> >         { .compatible = "qcom,rmtfs-mem" },
> >         { .compatible = "qcom,cmd-db" },
> > --
> > 2.22.0.770.g0f2c4a37fd-goog
> >

^ permalink raw reply

* Re: [PATCH v4 3/4] net: phy: realtek: Add helpers for accessing RTL8211E extension pages
From: Matthias Kaehlcke @ 2019-08-06 21:58 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: David S . Miller, Rob Herring, Mark Rutland, Andrew Lunn,
	Florian Fainelli, netdev, devicetree, linux-kernel,
	Douglas Anderson
In-Reply-To: <71d817b9-7bcc-9f83-331d-1c3958c41f51@gmail.com>

On Sun, Aug 04, 2019 at 10:33:30AM +0200, Heiner Kallweit wrote:
> On 01.08.2019 21:07, Matthias Kaehlcke wrote:
> > The RTL8211E has extension pages, which can be accessed after
> > selecting a page through a custom method. Add a function to
> > modify bits in a register of an extension page and a helper for
> > selecting an ext page. Use rtl8211e_modify_ext_paged() in
> > rtl8211e_config_init() instead of doing things 'manually'.
> > 
> > Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> > ---
> > Changes in v4:
> > - don't add constant RTL8211E_EXT_PAGE, it's only used once,
> >   use a literal instead
> > - pass 'oldpage' to phy_restore_page() in rtl8211e_select_ext_page(),
> >   not 'page'
> > - return 'oldpage' in rtl8211e_select_ext_page()
> > - use __phy_modify() in rtl8211e_modify_ext_paged() instead of
> >   reimplementing __phy_modify_changed()
> > - in rtl8211e_modify_ext_paged() return directly when
> >   rtl8211e_select_ext_page() fails
> > ---
> >  drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++------------
> >  1 file changed, 34 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
> > index a669945eb829..e09d3b0da2c7 100644
> > --- a/drivers/net/phy/realtek.c
> > +++ b/drivers/net/phy/realtek.c
> > @@ -53,6 +53,36 @@ static int rtl821x_write_page(struct phy_device *phydev, int page)
> >  	return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
> >  }
> >  
> > +static int rtl8211e_select_ext_page(struct phy_device *phydev, int page)
> 
> The "extended page" mechanism doesn't exist on RTL8211E only. A prefix
> rtl821x like in other functions may be better therefore.

Sounds good, I'll change it in the next revision

Thanks

Matthias

^ permalink raw reply

* Re: [PATCH v4 2/4] RISC-V: Add riscv_isa reprensenting ISA features common across CPUs
From: Paul Walmsley @ 2019-08-06 21:54 UTC (permalink / raw)
  To: Atish Patra, Anup Patel
  Cc: linux-kernel, Alan Kao, Albert Ou, Daniel Lezcano, devicetree,
	Enrico Weigelt, Greg Kroah-Hartman, Johan Hovold, linux-riscv,
	Mark Rutland, Palmer Dabbelt, Rob Herring, Thomas Gleixner
In-Reply-To: <20190803042723.7163-3-atish.patra@wdc.com>

Hi Anup, Atish,

On Fri, 2 Aug 2019, Atish Patra wrote:

> From: Anup Patel <anup.patel@wdc.com>
> 
> This patch adds riscv_isa integer to represent ISA features common
> across all CPUs. The riscv_isa is not same as elf_hwcap because
> elf_hwcap will only have ISA features relevant for user-space apps
> whereas riscv_isa will have ISA features relevant to both kernel
> and user-space apps.
> 
> One of the use case is KVM hypervisor where riscv_isa will be used
> to do following operations:
> 
> 1. Check whether hypervisor extension is available
> 2. Find ISA features that need to be virtualized (e.g. floating
>    point support, vector extension, etc.)
> 
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> Signed-off-by: Atish Patra <atish.patra@wdc.com>

Do you have any opinions on how this patch might change for the Z-prefix 
extensions?  This bitfield approach probably won't scale, and with the 
EXPORT_SYMBOL(), it might be worth trying to put together a approach that 
would work over the long term?


- Paul

^ permalink raw reply

* Re: [PATCH v7 01/20] pinctrl: tegra: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-06 21:54 UTC (permalink / raw)
  To: Dmitry Osipenko, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <36351140-afd4-38c4-3722-4ee0894287fa@gmail.com>


On 8/6/19 10:59 AM, Dmitry Osipenko wrote:
> 05.08.2019 21:06, Sowjanya Komatineni пишет:
>> On 8/5/19 3:50 AM, Dmitry Osipenko wrote:
>>> 01.08.2019 0:10, Sowjanya Komatineni пишет:
>>>> This patch adds support for Tegra pinctrl driver suspend and resume.
>>>>
>>>> During suspend, context of all pinctrl registers are stored and
>>>> on resume they are all restored to have all the pinmux and pad
>>>> configuration for normal operation.
>>>>
>>>> Acked-by: Thierry Reding <treding@nvidia.com>
>>>> Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>> ---
>>>>    drivers/pinctrl/tegra/pinctrl-tegra.c | 59
>>>> +++++++++++++++++++++++++++++++++++
>>>>    drivers/pinctrl/tegra/pinctrl-tegra.h |  3 ++
>>>>    2 files changed, 62 insertions(+)
>>>>
>>>> diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c
>>>> b/drivers/pinctrl/tegra/pinctrl-tegra.c
>>>> index 186ef98e7b2b..e3a237534281 100644
>>>> --- a/drivers/pinctrl/tegra/pinctrl-tegra.c
>>>> +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
>>>> @@ -631,6 +631,58 @@ static void
>>>> tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
>>>>        }
>>>>    }
>>>>    +static size_t tegra_pinctrl_get_bank_size(struct device *dev,
>>>> +                      unsigned int bank_id)
>>>> +{
>>>> +    struct platform_device *pdev = to_platform_device(dev);
>>>> +    struct resource *res;
>>>> +
>>>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, bank_id);
>>>> +
>>>> +    return resource_size(res) / 4;
>>>> +}
>>>> +
>>>> +static int tegra_pinctrl_suspend(struct device *dev)
>>>> +{
>>>> +    struct tegra_pmx *pmx = dev_get_drvdata(dev);
>>>> +    u32 *backup_regs = pmx->backup_regs;
>>>> +    u32 *regs;
>>>> +    size_t bank_size;
>>>> +    unsigned int i, k;
>>>> +
>>>> +    for (i = 0; i < pmx->nbanks; i++) {
>>>> +        bank_size = tegra_pinctrl_get_bank_size(dev, i);
>>>> +        regs = pmx->regs[i];
>>>> +        for (k = 0; k < bank_size; k++)
>>>> +            *backup_regs++ = readl_relaxed(regs++);
>>>> +    }
>>>> +
>>>> +    return pinctrl_force_sleep(pmx->pctl);
>>>> +}
>>>> +
>>>> +static int tegra_pinctrl_resume(struct device *dev)
>>>> +{
>>>> +    struct tegra_pmx *pmx = dev_get_drvdata(dev);
>>>> +    u32 *backup_regs = pmx->backup_regs;
>>>> +    u32 *regs;
>>>> +    size_t bank_size;
>>>> +    unsigned int i, k;
>>>> +
>>>> +    for (i = 0; i < pmx->nbanks; i++) {
>>>> +        bank_size = tegra_pinctrl_get_bank_size(dev, i);
>>>> +        regs = pmx->regs[i];
>>>> +        for (k = 0; k < bank_size; k++)
>>>> +            writel_relaxed(*backup_regs++, regs++);
>>>> +    }
>>> I'm now curious whether any kind of barrier is needed after the
>>> writings. The pmx_writel() doesn't insert a barrier after the write and
>>> seems it just misuses writel, which actually should be writel_relaxed()
>>> + barrier, IIUC.
>> pmx_writel uses writel and it has wmb before raw_write which complete
>> all writes initiated prior to this.
>>
>> By misusing writel, you mean to have barrier after register write?
> Yes, at least to me it doesn't make much sense for this driver to stall
> before the write. It's the pinctrl user which should be taking care
> about everything to be ready before making a change to the pinctrl's
> configuration.
>
>>> It's also not obvious whether PINCTRL HW has any kind of write-FIFO and
>>> thus maybe read-back + rmb() is needed in order ensure that writes are
>>> actually completed.
>> I believe adding write barrier wmb after writel_relaxed should be good
>> rather than doing readback + rmb
>>> The last thing which is not obvious is when the new configuration
>>> actually takes into effect, does it happen immediately or maybe some
>>> delay is needed?
>>>
>>> [snip]
>> Based on internal design there is no internal delay and it all depends
>> on APB rate that it takes to write to register.
>>
>> Pinmux value change to reflect internally might take couple of clock
>> cycles which is much faster than SW can read.
> Still not quite obvious if it's possible to have a case where some
> hardware is touched before necessary pinctrl change is fully completed
> and then to get into trouble because of it.

To be safer, will add write barrier after all writes in resume and also 
will have separate patch for pmx_writel fix to use writel_relaxed 
followed by write barrier.

Thanks

Sowjanya

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox