* Re: [PATCH] ibmvfc: Avoid link down on FS9100 canister reboot
From: Brian King @ 2020-09-16 12:42 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: tyreld, linuxppc-dev, linux-scsi
In-Reply-To: <yq1o8m61r87.fsf@ca-mkp.ca.oracle.com>
On 9/15/20 7:49 PM, Martin K. Petersen wrote:
>
> Brian,
>
>> When a canister on a FS9100, or similar storage, running in NPIV mode,
>> is rebooted, its WWPNs will fail over to another canister.
>
> [...]
>
> Applied to 5.10/scsi-staging, thanks! I fixed a bunch of checkpatch
> warnings.
Sorry about the checkpatch issues. Thanks for pulling this in.
-Brian
--
Brian King
Power Linux I/O
IBM Linux Technology Center
^ permalink raw reply
* Re: [PATCH v3] pseries/hotplug-memory: hot-add: skip redundant LMB lookup
From: Scott Cheloha @ 2020-09-16 14:39 UTC (permalink / raw)
To: David Hildenbrand
Cc: Nathan Lynch, linuxppc-dev, Michal Suchanek, Laurent Dufour,
Rick Lindsley
In-Reply-To: <5c6abee9-5ab1-d509-59ab-21ad1a7be14d@redhat.com>
On Wed, Sep 16, 2020 at 09:39:53AM +0200, David Hildenbrand wrote:
> On 15.09.20 21:46, Scott Cheloha wrote:
> > During memory hot-add, dlpar_add_lmb() calls memory_add_physaddr_to_nid()
> > to determine which node id (nid) to use when later calling __add_memory().
> >
> > This is wasteful. On pseries, memory_add_physaddr_to_nid() finds an
> > appropriate nid for a given address by looking up the LMB containing the
> > address and then passing that LMB to of_drconf_to_nid_single() to get the
> > nid. In dlpar_add_lmb() we get this address from the LMB itself.
> >
> > In short, we have a pointer to an LMB and then we are searching for
> > that LMB *again* in order to find its nid.
> >
> > If we call of_drconf_to_nid_single() directly from dlpar_add_lmb() we
> > can skip the redundant lookup. The only error handling we need to
> > duplicate from memory_add_physaddr_to_nid() is the fallback to the
> > default nid when drconf_to_nid_single() returns -1 (NUMA_NO_NODE) or
> > an invalid nid.
> >
> > Skipping the extra lookup makes hot-add operations faster, especially
> > on machines with many LMBs.
> >
> > Consider an LPAR with 126976 LMBs. In one test, hot-adding 126000
> > LMBs on an upatched kernel took ~3.5 hours while a patched kernel
> > completed the same operation in ~2 hours:
> >
> > Unpatched (12450 seconds):
> > Sep 9 04:06:31 ltc-brazos1 drmgr[810169]: drmgr: -c mem -a -q 126000
> > Sep 9 04:06:31 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
> > [...]
> > Sep 9 07:34:01 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
> >
> > Patched (7065 seconds):
> > Sep 8 21:49:57 ltc-brazos1 drmgr[877703]: drmgr: -c mem -a -q 126000
> > Sep 8 21:49:57 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
> > [...]
> > Sep 8 23:27:42 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
> >
> > It should be noted that the speedup grows more substantial when
> > hot-adding LMBs at the end of the drconf range. This is because we
> > are skipping a linear LMB search.
> >
> > To see the distinction, consider smaller hot-add test on the same
> > LPAR. A perf-stat run with 10 iterations showed that hot-adding 4096
> > LMBs completed less than 1 second faster on a patched kernel:
> >
> > Unpatched:
> > Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
> >
> > 104,753.42 msec task-clock # 0.992 CPUs utilized ( +- 0.55% )
> > 4,708 context-switches # 0.045 K/sec ( +- 0.69% )
> > 2,444 cpu-migrations # 0.023 K/sec ( +- 1.25% )
> > 394 page-faults # 0.004 K/sec ( +- 0.22% )
> > 445,902,503,057 cycles # 4.257 GHz ( +- 0.55% ) (66.67%)
> > 8,558,376,740 stalled-cycles-frontend # 1.92% frontend cycles idle ( +- 0.88% ) (49.99%)
> > 300,346,181,651 stalled-cycles-backend # 67.36% backend cycles idle ( +- 0.76% ) (50.01%)
> > 258,091,488,691 instructions # 0.58 insn per cycle
> > # 1.16 stalled cycles per insn ( +- 0.22% ) (66.67%)
> > 70,568,169,256 branches # 673.660 M/sec ( +- 0.17% ) (50.01%)
> > 3,100,725,426 branch-misses # 4.39% of all branches ( +- 0.20% ) (49.99%)
> >
> > 105.583 +- 0.589 seconds time elapsed ( +- 0.56% )
> >
> > Patched:
> > Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
> >
> > 104,055.69 msec task-clock # 0.993 CPUs utilized ( +- 0.32% )
> > 4,606 context-switches # 0.044 K/sec ( +- 0.20% )
> > 2,463 cpu-migrations # 0.024 K/sec ( +- 0.93% )
> > 394 page-faults # 0.004 K/sec ( +- 0.25% )
> > 442,951,129,921 cycles # 4.257 GHz ( +- 0.32% ) (66.66%)
> > 8,710,413,329 stalled-cycles-frontend # 1.97% frontend cycles idle ( +- 0.47% ) (50.06%)
> > 299,656,905,836 stalled-cycles-backend # 67.65% backend cycles idle ( +- 0.39% ) (50.02%)
> > 252,731,168,193 instructions # 0.57 insn per cycle
> > # 1.19 stalled cycles per insn ( +- 0.20% ) (66.66%)
> > 68,902,851,121 branches # 662.173 M/sec ( +- 0.13% ) (49.94%)
> > 3,100,242,882 branch-misses # 4.50% of all branches ( +- 0.15% ) (49.98%)
> >
> > 104.829 +- 0.325 seconds time elapsed ( +- 0.31% )
> >
> > This is consistent. An add-by-count hot-add operation adds LMBs
> > greedily, so LMBs near the start of the drconf range are considered
> > first. On an otherwise idle LPAR with so many LMBs we would expect to
> > find the LMBs we need near the start of the drconf range, hence the
> > smaller speedup.
> >
> > Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
>
>
> Hi Scott,
>
> IIRC, ppc DLPAR does a single add_memory() [...]
Yes.
> [...] for each LMB (16 MB).
The block size is set by the hypervisor. The default is 256MB. In
this test I had a block size of 256MB.
On multi-terabyte machines I would effectively always expect a block
size of 256MB. 16MB blocks are supported, but it is not the default
setting so it is increasingly rare.
> With tons of LMBs, this will also make /proc/iomem explode in size (using a
> list-based tree), making traversal significantly slower e.g., on
> insertions and system ram walks.
>
> I was wondering if you would get another performance boost under ppc
> when using MEMHP_MERGE_RESOURCE [1]. AFAIKs, the resource boundaries are
> not of interest. No guarantees, might be worth a try.
I'll give it a shot.
> Did you investigate what else makes memory hotplug that slow? (126000
> LMBs correspond to roughly 2TB, that shouldn't take 2 hours ...)
It was about ~31TB in 256MB blocks. It's a worst-case test (add all
the memory), but I'm pretty happy with a 1.5 hour improvement :)
> Memory block devices might still be a slowdown (although we have an
> xarray in place now that takes care of most pain).
Memory block devices are no longer a hotspot.
Some of the slowdown is in the printk overhead. We print a log for
every LMB. It is very silly. I intend to move those to a debug
priority, which should trivially speed things up.
Otherwise I need to do more profiling.
^ permalink raw reply
* Re: [PATCH v3] pseries/hotplug-memory: hot-add: skip redundant LMB lookup
From: David Hildenbrand @ 2020-09-16 14:45 UTC (permalink / raw)
To: Scott Cheloha
Cc: Nathan Lynch, linuxppc-dev, Michal Suchanek, Laurent Dufour,
Rick Lindsley
In-Reply-To: <20200916143913.o4o63mh4mums2qfm@rascal.austin.ibm.com>
On 16.09.20 16:39, Scott Cheloha wrote:
> On Wed, Sep 16, 2020 at 09:39:53AM +0200, David Hildenbrand wrote:
>> On 15.09.20 21:46, Scott Cheloha wrote:
>>> During memory hot-add, dlpar_add_lmb() calls memory_add_physaddr_to_nid()
>>> to determine which node id (nid) to use when later calling __add_memory().
>>>
>>> This is wasteful. On pseries, memory_add_physaddr_to_nid() finds an
>>> appropriate nid for a given address by looking up the LMB containing the
>>> address and then passing that LMB to of_drconf_to_nid_single() to get the
>>> nid. In dlpar_add_lmb() we get this address from the LMB itself.
>>>
>>> In short, we have a pointer to an LMB and then we are searching for
>>> that LMB *again* in order to find its nid.
>>>
>>> If we call of_drconf_to_nid_single() directly from dlpar_add_lmb() we
>>> can skip the redundant lookup. The only error handling we need to
>>> duplicate from memory_add_physaddr_to_nid() is the fallback to the
>>> default nid when drconf_to_nid_single() returns -1 (NUMA_NO_NODE) or
>>> an invalid nid.
>>>
>>> Skipping the extra lookup makes hot-add operations faster, especially
>>> on machines with many LMBs.
>>>
>>> Consider an LPAR with 126976 LMBs. In one test, hot-adding 126000
>>> LMBs on an upatched kernel took ~3.5 hours while a patched kernel
>>> completed the same operation in ~2 hours:
>>>
>>> Unpatched (12450 seconds):
>>> Sep 9 04:06:31 ltc-brazos1 drmgr[810169]: drmgr: -c mem -a -q 126000
>>> Sep 9 04:06:31 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
>>> [...]
>>> Sep 9 07:34:01 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
>>>
>>> Patched (7065 seconds):
>>> Sep 8 21:49:57 ltc-brazos1 drmgr[877703]: drmgr: -c mem -a -q 126000
>>> Sep 8 21:49:57 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
>>> [...]
>>> Sep 8 23:27:42 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
>>>
>>> It should be noted that the speedup grows more substantial when
>>> hot-adding LMBs at the end of the drconf range. This is because we
>>> are skipping a linear LMB search.
>>>
>>> To see the distinction, consider smaller hot-add test on the same
>>> LPAR. A perf-stat run with 10 iterations showed that hot-adding 4096
>>> LMBs completed less than 1 second faster on a patched kernel:
>>>
>>> Unpatched:
>>> Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
>>>
>>> 104,753.42 msec task-clock # 0.992 CPUs utilized ( +- 0.55% )
>>> 4,708 context-switches # 0.045 K/sec ( +- 0.69% )
>>> 2,444 cpu-migrations # 0.023 K/sec ( +- 1.25% )
>>> 394 page-faults # 0.004 K/sec ( +- 0.22% )
>>> 445,902,503,057 cycles # 4.257 GHz ( +- 0.55% ) (66.67%)
>>> 8,558,376,740 stalled-cycles-frontend # 1.92% frontend cycles idle ( +- 0.88% ) (49.99%)
>>> 300,346,181,651 stalled-cycles-backend # 67.36% backend cycles idle ( +- 0.76% ) (50.01%)
>>> 258,091,488,691 instructions # 0.58 insn per cycle
>>> # 1.16 stalled cycles per insn ( +- 0.22% ) (66.67%)
>>> 70,568,169,256 branches # 673.660 M/sec ( +- 0.17% ) (50.01%)
>>> 3,100,725,426 branch-misses # 4.39% of all branches ( +- 0.20% ) (49.99%)
>>>
>>> 105.583 +- 0.589 seconds time elapsed ( +- 0.56% )
>>>
>>> Patched:
>>> Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
>>>
>>> 104,055.69 msec task-clock # 0.993 CPUs utilized ( +- 0.32% )
>>> 4,606 context-switches # 0.044 K/sec ( +- 0.20% )
>>> 2,463 cpu-migrations # 0.024 K/sec ( +- 0.93% )
>>> 394 page-faults # 0.004 K/sec ( +- 0.25% )
>>> 442,951,129,921 cycles # 4.257 GHz ( +- 0.32% ) (66.66%)
>>> 8,710,413,329 stalled-cycles-frontend # 1.97% frontend cycles idle ( +- 0.47% ) (50.06%)
>>> 299,656,905,836 stalled-cycles-backend # 67.65% backend cycles idle ( +- 0.39% ) (50.02%)
>>> 252,731,168,193 instructions # 0.57 insn per cycle
>>> # 1.19 stalled cycles per insn ( +- 0.20% ) (66.66%)
>>> 68,902,851,121 branches # 662.173 M/sec ( +- 0.13% ) (49.94%)
>>> 3,100,242,882 branch-misses # 4.50% of all branches ( +- 0.15% ) (49.98%)
>>>
>>> 104.829 +- 0.325 seconds time elapsed ( +- 0.31% )
>>>
>>> This is consistent. An add-by-count hot-add operation adds LMBs
>>> greedily, so LMBs near the start of the drconf range are considered
>>> first. On an otherwise idle LPAR with so many LMBs we would expect to
>>> find the LMBs we need near the start of the drconf range, hence the
>>> smaller speedup.
>>>
>>> Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
>>
>>
>> Hi Scott,
>>
>> IIRC, ppc DLPAR does a single add_memory() [...]
>
> Yes.
>
>> [...] for each LMB (16 MB).
>
> The block size is set by the hypervisor. The default is 256MB. In
> this test I had a block size of 256MB.
Oh, I wasn't aware that it's configurable, thanks for pointing that out
(missed the custom memory_block_size_bytes() implementation).
I wonder how it works with pseries_remove_memblock(), that uses
MIN_MEMORY_BLOCK_SIZE with __remove_memory() - that will always BUG_ON
in try_remove_memory() with BUG_ON(check_hotplug_memory_range(start,
size)) in case the size is < memory_block_size_bytes().
Maybe that's not called on such machines ...
>
> On multi-terabyte machines I would effectively always expect a block
> size of 256MB. 16MB blocks are supported, but it is not the default
> setting so it is increasingly rare.>
>> With tons of LMBs, this will also make /proc/iomem explode in size (using a
>> list-based tree), making traversal significantly slower e.g., on
>> insertions and system ram walks.
>>
>> I was wondering if you would get another performance boost under ppc
>> when using MEMHP_MERGE_RESOURCE [1]. AFAIKs, the resource boundaries are
>> not of interest. No guarantees, might be worth a try.
>
> I'll give it a shot.
>
>> Did you investigate what else makes memory hotplug that slow? (126000
>> LMBs correspond to roughly 2TB, that shouldn't take 2 hours ...)
>
> It was about ~31TB in 256MB blocks. It's a worst-case test (add all
> the memory), but I'm pretty happy with a 1.5 hour improvement :)
Yeah, definitely :)
--
Thanks,
David / dhildenb
^ permalink raw reply
* [PATCH v4] pseries/hotplug-memory: hot-add: skip redundant LMB lookup
From: Scott Cheloha @ 2020-09-16 14:51 UTC (permalink / raw)
To: linuxppc-dev
Cc: Nathan Lynch, Michal Suchanek, Laurent Dufour, David Hildenbrand,
Rick Lindsley
During memory hot-add, dlpar_add_lmb() calls memory_add_physaddr_to_nid()
to determine which node id (nid) to use when later calling __add_memory().
This is wasteful. On pseries, memory_add_physaddr_to_nid() finds an
appropriate nid for a given address by looking up the LMB containing the
address and then passing that LMB to of_drconf_to_nid_single() to get the
nid. In dlpar_add_lmb() we get this address from the LMB itself.
In short, we have a pointer to an LMB and then we are searching for
that LMB *again* in order to find its nid.
If we call of_drconf_to_nid_single() directly from dlpar_add_lmb() we
can skip the redundant lookup. The only error handling we need to
duplicate from memory_add_physaddr_to_nid() is the fallback to the
default nid when drconf_to_nid_single() returns -1 (NUMA_NO_NODE) or
an invalid nid.
Skipping the extra lookup makes hot-add operations faster, especially
on machines with many LMBs.
Consider an LPAR with 126976 LMBs. In one test, hot-adding 126000
LMBs on an upatched kernel took ~3.5 hours while a patched kernel
completed the same operation in ~2 hours:
Unpatched (12450 seconds):
Sep 9 04:06:31 ltc-brazos1 drmgr[810169]: drmgr: -c mem -a -q 126000
Sep 9 04:06:31 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
[...]
Sep 9 07:34:01 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
Patched (7065 seconds):
Sep 8 21:49:57 ltc-brazos1 drmgr[877703]: drmgr: -c mem -a -q 126000
Sep 8 21:49:57 ltc-brazos1 kernel: pseries-hotplug-mem: Attempting to hot-add 126000 LMB(s)
[...]
Sep 8 23:27:42 ltc-brazos1 kernel: pseries-hotplug-mem: Memory at 20000000 (drc index 80000002) was hot-added
It should be noted that the speedup grows more substantial when
hot-adding LMBs at the end of the drconf range. This is because we
are skipping a linear LMB search.
To see the distinction, consider smaller hot-add test on the same
LPAR. A perf-stat run with 10 iterations showed that hot-adding 4096
LMBs completed less than 1 second faster on a patched kernel:
Unpatched:
Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
104,753.42 msec task-clock # 0.992 CPUs utilized ( +- 0.55% )
4,708 context-switches # 0.045 K/sec ( +- 0.69% )
2,444 cpu-migrations # 0.023 K/sec ( +- 1.25% )
394 page-faults # 0.004 K/sec ( +- 0.22% )
445,902,503,057 cycles # 4.257 GHz ( +- 0.55% ) (66.67%)
8,558,376,740 stalled-cycles-frontend # 1.92% frontend cycles idle ( +- 0.88% ) (49.99%)
300,346,181,651 stalled-cycles-backend # 67.36% backend cycles idle ( +- 0.76% ) (50.01%)
258,091,488,691 instructions # 0.58 insn per cycle
# 1.16 stalled cycles per insn ( +- 0.22% ) (66.67%)
70,568,169,256 branches # 673.660 M/sec ( +- 0.17% ) (50.01%)
3,100,725,426 branch-misses # 4.39% of all branches ( +- 0.20% ) (49.99%)
105.583 +- 0.589 seconds time elapsed ( +- 0.56% )
Patched:
Performance counter stats for 'drmgr -c mem -a -q 4096' (10 runs):
104,055.69 msec task-clock # 0.993 CPUs utilized ( +- 0.32% )
4,606 context-switches # 0.044 K/sec ( +- 0.20% )
2,463 cpu-migrations # 0.024 K/sec ( +- 0.93% )
394 page-faults # 0.004 K/sec ( +- 0.25% )
442,951,129,921 cycles # 4.257 GHz ( +- 0.32% ) (66.66%)
8,710,413,329 stalled-cycles-frontend # 1.97% frontend cycles idle ( +- 0.47% ) (50.06%)
299,656,905,836 stalled-cycles-backend # 67.65% backend cycles idle ( +- 0.39% ) (50.02%)
252,731,168,193 instructions # 0.57 insn per cycle
# 1.19 stalled cycles per insn ( +- 0.20% ) (66.66%)
68,902,851,121 branches # 662.173 M/sec ( +- 0.13% ) (49.94%)
3,100,242,882 branch-misses # 4.50% of all branches ( +- 0.15% ) (49.98%)
104.829 +- 0.325 seconds time elapsed ( +- 0.31% )
This is consistent. An add-by-count hot-add operation adds LMBs
greedily, so LMBs near the start of the drconf range are considered
first. On an otherwise idle LPAR with so many LMBs we would expect to
find the LMBs we need near the start of the drconf range, hence the
smaller speedup.
Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
---
Changelog:
v1: https://lore.kernel.org/linuxppc-dev/20200910175637.2865160-1-cheloha@linux.ibm.com/
v2:
- Move prototype for of_drconf_to_nid_single() to topology.h.
Requested by Michael Ellerman.
v3:
- Send the right patch. v2 is from the wrong branch, my mistake.
v4:
- Fix checkpatch.pl warnings. Reported by Laurent Dufour.
arch/powerpc/include/asm/topology.h | 3 +++
arch/powerpc/mm/numa.c | 2 +-
arch/powerpc/platforms/pseries/hotplug-memory.c | 6 ++++--
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index f0b6300e7dd3..ae19b19f9d44 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -86,6 +86,9 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
#endif /* CONFIG_NUMA */
+struct drmem_lmb;
+int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+
#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
extern int find_and_online_cpu_nid(int cpu);
#else
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 1f61fa2148b5..63507b47164d 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -430,7 +430,7 @@ static int of_get_assoc_arrays(struct assoc_arrays *aa)
* This is like of_node_to_nid_single() for memory represented in the
* ibm,dynamic-reconfiguration-memory node.
*/
-static int of_drconf_to_nid_single(struct drmem_lmb *lmb)
+int of_drconf_to_nid_single(struct drmem_lmb *lmb)
{
struct assoc_arrays aa = { .arrays = NULL };
int default_nid = NUMA_NO_NODE;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 0ea976d1cac4..9a533acf8ad0 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -611,8 +611,10 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
block_sz = memory_block_size_bytes();
- /* Find the node id for this address. */
- nid = memory_add_physaddr_to_nid(lmb->base_addr);
+ /* Find the node id for this LMB. Fake one if necessary. */
+ nid = of_drconf_to_nid_single(lmb);
+ if (nid < 0 || !node_possible(nid))
+ nid = first_online_node;
/* Add the memory */
rc = __add_memory(nid, lmb->base_addr, block_sz);
--
2.24.1
^ permalink raw reply related
* Re: [PATCH] ASoC: fsl_audmix: make clock and output src write only
From: Nicolin Chen @ 2020-09-17 0:10 UTC (permalink / raw)
To: Viorel Suman (OSS)
Cc: alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li, Fabio Estevam,
Takashi Iwai, Liam Girdwood, Jaroslav Kysela, Viorel Suman,
Mark Brown, NXP Linux Team, Viorel Suman, Shengjiu Wang,
linux-kernel
In-Reply-To: <1600104274-13110-1-git-send-email-viorel.suman@oss.nxp.com>
On Mon, Sep 14, 2020 at 08:24:34PM +0300, Viorel Suman (OSS) wrote:
> From: Viorel Suman <viorel.suman@nxp.com>
>
> "alsactl -f state.conf store/restore" sequence fails because setting
> "mixing clock source" and "output source" requires active TDM clock
> being started for configuration propagation. Make these two controls
> write only so that their values are not stored at "alsactl store".
>
> Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> sound/soc/fsl/fsl_audmix.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
> index a447baf..7ad5925 100644
> --- a/sound/soc/fsl/fsl_audmix.c
> +++ b/sound/soc/fsl/fsl_audmix.c
> @@ -199,10 +199,18 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
>
> static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
> /* FSL_AUDMIX_CTR controls */
> - SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
> - snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
> - SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
> - snd_soc_get_enum_double, fsl_audmix_put_out_src),
> + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> + .name = "Mixing Clock Source",
> + .info = snd_soc_info_enum_double,
> + .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
> + .put = fsl_audmix_put_mix_clk_src,
> + .private_value = (unsigned long)&fsl_audmix_enum[0] },
> + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> + .name = "Output Source",
> + .info = snd_soc_info_enum_double,
> + .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
> + .put = fsl_audmix_put_out_src,
> + .private_value = (unsigned long)&fsl_audmix_enum[1] },
> SOC_ENUM("Output Width", fsl_audmix_enum[2]),
> SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
> SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH] ibmvfc: Protect vhost->task_set increment by the host lock
From: Brian King @ 2020-09-16 20:09 UTC (permalink / raw)
To: linux-scsi; +Cc: Brian King, tyreld, linuxppc-dev, martin.petersen
In the discovery thread, ibmvfc does a vhost->task_set++ without
any lock held. This could result in two targets getting the same
cancel key, which could have strange effects in error recovery.
The actual probability of this occurring should be extremely
small, since this should all be done in a single threaded loop
from the discovery thread, but let's fix it up anyway to be safe.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 322bb30..b393587 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -4169,11 +4169,11 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost,struct ibmvfc_discover_
tgt->wwpn = wwpn;
tgt->vhost = vhost;
tgt->need_login = 1;
- tgt->cancel_key = vhost->task_set++;
timer_setup(&tgt->timer, ibmvfc_adisc_timeout, 0);
kref_init(&tgt->kref);
ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
spin_lock_irqsave(vhost->host->host_lock, flags);
+ tgt->cancel_key = vhost->task_set++;
list_add_tail(&tgt->queue, &vhost->targets);
unlock_out:
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2] powerpc: fix EDEADLOCK redefinition error in uapi/asm/errno.h
From: Tony Ambardar @ 2020-09-17 0:07 UTC (permalink / raw)
To: Michael Ellerman
Cc: Tony Ambardar, linux-kernel, Paul Mackerras, Rosen Penev, bpf,
linuxppc-dev
In-Reply-To: <20200916074214.995128-1-Tony.Ambardar@gmail.com>
A few archs like powerpc have different errno.h values for macros
EDEADLOCK and EDEADLK. In code including both libc and linux versions of
errno.h, this can result in multiple definitions of EDEADLOCK in the
include chain. Definitions to the same value (e.g. seen with mips) do
not raise warnings, but on powerpc there are redefinitions changing the
value, which raise warnings and errors (if using "-Werror").
Guard against these redefinitions to avoid build errors like the following,
first seen cross-compiling libbpf v5.8.9 for powerpc using GCC 8.4.0 with
musl 1.1.24:
In file included from ../../arch/powerpc/include/uapi/asm/errno.h:5,
from ../../include/linux/err.h:8,
from libbpf.c:29:
../../include/uapi/asm-generic/errno.h:40: error: "EDEADLOCK" redefined [-Werror]
#define EDEADLOCK EDEADLK
In file included from toolchain-powerpc_8540_gcc-8.4.0_musl/include/errno.h:10,
from libbpf.c:26:
toolchain-powerpc_8540_gcc-8.4.0_musl/include/bits/errno.h:58: note: this is the location of the previous definition
#define EDEADLOCK 58
cc1: all warnings being treated as errors
Fixes: 95f28190aa01 ("tools include arch: Grab a copy of errno.h for arch's supported by perf")
Fixes: c3617f72036c ("UAPI: (Scripted) Disintegrate arch/powerpc/include/asm")
Reported-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
---
v1 -> v2:
* clean up commit description formatting
---
arch/powerpc/include/uapi/asm/errno.h | 1 +
tools/arch/powerpc/include/uapi/asm/errno.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/powerpc/include/uapi/asm/errno.h b/arch/powerpc/include/uapi/asm/errno.h
index cc79856896a1..4ba87de32be0 100644
--- a/arch/powerpc/include/uapi/asm/errno.h
+++ b/arch/powerpc/include/uapi/asm/errno.h
@@ -2,6 +2,7 @@
#ifndef _ASM_POWERPC_ERRNO_H
#define _ASM_POWERPC_ERRNO_H
+#undef EDEADLOCK
#include <asm-generic/errno.h>
#undef EDEADLOCK
diff --git a/tools/arch/powerpc/include/uapi/asm/errno.h b/tools/arch/powerpc/include/uapi/asm/errno.h
index cc79856896a1..4ba87de32be0 100644
--- a/tools/arch/powerpc/include/uapi/asm/errno.h
+++ b/tools/arch/powerpc/include/uapi/asm/errno.h
@@ -2,6 +2,7 @@
#ifndef _ASM_POWERPC_ERRNO_H
#define _ASM_POWERPC_ERRNO_H
+#undef EDEADLOCK
#include <asm-generic/errno.h>
#undef EDEADLOCK
--
2.25.1
^ permalink raw reply related
* [PATCH 1/3] powerpc/mce: remove nmi_enter/exit from real mode handler
From: Ganesh Goudar @ 2020-09-16 17:22 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: mahesh, msuchanek, Ganesh Goudar, npiggin
In-Reply-To: <20200916172228.83271-1-ganeshgr@linux.ibm.com>
Use of nmi_enter/exit in real mode handler causes the kernel to panic
and reboot on injecting slb mutihit on pseries machine running in hash
mmu mode, As these calls try to accesses memory outside RMO region in
real mode handler where translation is disabled.
Add check to not to use these calls on pseries machine running in hash
mmu mode.
Fixes: 116ac378bb3f ("powerpc/64s: machine check interrupt update NMI accounting")
Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
---
arch/powerpc/kernel/mce.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index ada59f6c4298..1d42fe0f5f9c 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -591,10 +591,15 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info);
long notrace machine_check_early(struct pt_regs *regs)
{
long handled = 0;
- bool nested = in_nmi();
+ bool nested;
+ bool is_pseries_hpt_guest;
u8 ftrace_enabled = this_cpu_get_ftrace_enabled();
this_cpu_set_ftrace_enabled(0);
+ is_pseries_hpt_guest = machine_is(pseries) &&
+ mmu_has_feature(MMU_FTR_HPTE_TABLE);
+ /* Do not use nmi_enter/exit for pseries hpte guest */
+ nested = is_pseries_hpt_guest ? true : in_nmi();
if (!nested)
nmi_enter();
--
2.26.2
^ permalink raw reply related
* [PATCH 3/3] selftest/powerpc: Add slb multihit selftest
From: Ganesh Goudar @ 2020-09-16 17:22 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: mahesh, msuchanek, Ganesh Goudar, npiggin
In-Reply-To: <20200916172228.83271-1-ganeshgr@linux.ibm.com>
Add selftest to check if the system recovers from slb multihit
errors.
Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
---
tools/testing/selftests/powerpc/Makefile | 3 ++-
tools/testing/selftests/powerpc/mces/Makefile | 6 ++++++
tools/testing/selftests/powerpc/mces/slb_multihit.sh | 9 +++++++++
3 files changed, 17 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/mces/Makefile
create mode 100755 tools/testing/selftests/powerpc/mces/slb_multihit.sh
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 0830e63818c1..3c900b30da79 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -31,7 +31,8 @@ SUB_DIRS = alignment \
vphn \
math \
ptrace \
- security
+ security \
+ mces
endif
diff --git a/tools/testing/selftests/powerpc/mces/Makefile b/tools/testing/selftests/powerpc/mces/Makefile
new file mode 100644
index 000000000000..5a356295e952
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mces/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for machine check exceptions selftests
+
+TEST_PROGS := slb_multihit.sh
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/mces/slb_multihit.sh b/tools/testing/selftests/powerpc/mces/slb_multihit.sh
new file mode 100755
index 000000000000..35c17c619d0a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mces/slb_multihit.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+if [ ! -e "/sys/kernel/debug/powerpc/mce_error_inject/inject_slb_multihit" ] ; then
+ exit 0;
+fi
+
+echo 1 > /sys/kernel/debug/powerpc/mce_error_inject/inject_slb_multihit
+exit 0
--
2.26.2
^ permalink raw reply related
* [PATCH 0/3] powerpc/mce: Fix mce handler and add selftest
From: Ganesh Goudar @ 2020-09-16 17:22 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: mahesh, msuchanek, Ganesh Goudar, npiggin
This patch series fixes mce handling for pseries, provides debugfs
interface for mce injection and adds selftest to test mce handling
on pseries/powernv machines running in hash mmu mode.
debugfs interface and sleftest are added only for slb multihit
injection, We can add other tests in future if possible.
Ganesh Goudar (3):
powerpc/mce: remove nmi_enter/exit from real mode handler
powerpc/mce: Add debugfs interface to inject MCE
selftest/powerpc: Add slb multihit selftest
arch/powerpc/Kconfig.debug | 9 ++
arch/powerpc/kernel/mce.c | 7 +-
arch/powerpc/sysdev/Makefile | 2 +
arch/powerpc/sysdev/mce_error_inject.c | 149 ++++++++++++++++++
tools/testing/selftests/powerpc/Makefile | 3 +-
tools/testing/selftests/powerpc/mces/Makefile | 6 +
.../selftests/powerpc/mces/slb_multihit.sh | 9 ++
7 files changed, 183 insertions(+), 2 deletions(-)
create mode 100644 arch/powerpc/sysdev/mce_error_inject.c
create mode 100644 tools/testing/selftests/powerpc/mces/Makefile
create mode 100755 tools/testing/selftests/powerpc/mces/slb_multihit.sh
--
2.26.2
^ permalink raw reply
* [PATCH 2/3] powerpc/mce: Add debugfs interface to inject MCE
From: Ganesh Goudar @ 2020-09-16 17:22 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: mahesh, msuchanek, Ganesh Goudar, npiggin
In-Reply-To: <20200916172228.83271-1-ganeshgr@linux.ibm.com>
To test machine check handling, add debugfs interface to inject
slb multihit errors.
To inject slb multihit:
#echo 1 > /sys/kernel/debug/powerpc/mce_error_inject/inject_slb_multihit
Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/Kconfig.debug | 9 ++
arch/powerpc/sysdev/Makefile | 2 +
arch/powerpc/sysdev/mce_error_inject.c | 148 +++++++++++++++++++++++++
3 files changed, 159 insertions(+)
create mode 100644 arch/powerpc/sysdev/mce_error_inject.c
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index b88900f4832f..61db133f2f0d 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -398,3 +398,12 @@ config KASAN_SHADOW_OFFSET
hex
depends on KASAN
default 0xe0000000
+
+config MCE_ERROR_INJECT
+ bool "Enable MCE error injection through debugfs"
+ depends on DEBUG_FS
+ default y
+ help
+ This option creates an mce_error_inject directory in the
+ powerpc debugfs directory that allows limited injection of
+ Machine Check Errors (MCEs).
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 026b3f01a991..7fc102222b77 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -52,3 +52,5 @@ obj-$(CONFIG_PPC_XICS) += xics/
obj-$(CONFIG_PPC_XIVE) += xive/
obj-$(CONFIG_GE_FPGA) += ge/
+
+obj-$(CONFIG_MCE_ERROR_INJECT) += mce_error_inject.o
diff --git a/arch/powerpc/sysdev/mce_error_inject.c b/arch/powerpc/sysdev/mce_error_inject.c
new file mode 100644
index 000000000000..ca4726bfa2d9
--- /dev/null
+++ b/arch/powerpc/sysdev/mce_error_inject.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Machine Check Exception injection code
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <asm/debugfs.h>
+
+static inline unsigned long get_slb_index(void)
+{
+ unsigned long index;
+
+ index = get_paca()->stab_rr;
+
+ /*
+ * simple round-robin replacement of slb starting at SLB_NUM_BOLTED.
+ */
+ if (index < (mmu_slb_size - 1))
+ index++;
+ else
+ index = SLB_NUM_BOLTED;
+ get_paca()->stab_rr = index;
+ return index;
+}
+
+#define slb_esid_mask(ssize) \
+ (((ssize) == MMU_SEGSIZE_256M) ? ESID_MASK : ESID_MASK_1T)
+
+static inline unsigned long mk_esid_data(unsigned long ea, int ssize,
+ unsigned long slot)
+{
+ return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot;
+}
+
+#define slb_vsid_shift(ssize) \
+ ((ssize) == MMU_SEGSIZE_256M ? SLB_VSID_SHIFT : SLB_VSID_SHIFT_1T)
+
+static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
+ unsigned long flags)
+{
+ return (get_kernel_vsid(ea, ssize) << slb_vsid_shift(ssize)) | flags |
+ ((unsigned long)ssize << SLB_VSID_SSIZE_SHIFT);
+}
+
+static void insert_slb_entry(char *p, int ssize)
+{
+ unsigned long flags, entry;
+ struct paca_struct *paca;
+
+ flags = SLB_VSID_KERNEL | mmu_psize_defs[MMU_PAGE_64K].sllp;
+
+ preempt_disable();
+
+ paca = get_paca();
+
+ entry = get_slb_index();
+ asm volatile("slbmte %0,%1" :
+ : "r" (mk_vsid_data((unsigned long)p, ssize, flags)),
+ "r" (mk_esid_data((unsigned long)p, ssize, entry))
+ : "memory");
+
+ entry = get_slb_index();
+ asm volatile("slbmte %0,%1" :
+ : "r" (mk_vsid_data((unsigned long)p, ssize, flags)),
+ "r" (mk_esid_data((unsigned long)p, ssize, entry))
+ : "memory");
+ preempt_enable();
+ p[0] = '!';
+}
+
+static void inject_vmalloc_slb_multihit(void)
+{
+ char *p;
+
+ p = vmalloc(2048);
+ if (!p)
+ return;
+
+ insert_slb_entry(p, MMU_SEGSIZE_1T);
+ vfree(p);
+}
+
+static void inject_kmalloc_slb_multihit(void)
+{
+ char *p;
+
+ p = kmalloc(2048, GFP_KERNEL);
+ if (!p)
+ return;
+
+ insert_slb_entry(p, MMU_SEGSIZE_1T);
+ kfree(p);
+}
+
+static ssize_t inject_slb_multihit(const char __user *u_buf, size_t count)
+{
+ char buf[32];
+ size_t buf_size;
+
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, u_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = '\0';
+
+ if (buf[0] != '1')
+ return -EINVAL;
+
+ inject_vmalloc_slb_multihit();
+ inject_kmalloc_slb_multihit();
+ return count;
+}
+
+static ssize_t inject_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ static ssize_t (*func)(const char __user *, size_t);
+
+ func = file->f_inode->i_private;
+ return func(buf, count);
+}
+
+static const struct file_operations inject_fops = {
+ .write = inject_write,
+ .llseek = default_llseek,
+};
+
+static int mce_error_inject_setup(void)
+{
+ struct dentry *mce_error_inject_dir;
+
+ mce_error_inject_dir = debugfs_create_dir("mce_error_inject",
+ powerpc_debugfs_root);
+
+ if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) {
+ (void)debugfs_create_file("inject_slb_multihit", 0200,
+ mce_error_inject_dir,
+ &inject_slb_multihit,
+ &inject_fops);
+ }
+
+ return 0;
+}
+
+device_initcall(mce_error_inject_setup);
--
2.26.2
^ permalink raw reply related
* Re: [PATCH 1/3] ASoC: fsl_sai: Add new added registers and new bit definition
From: Fabio Estevam @ 2020-09-16 17:03 UTC (permalink / raw)
To: Shengjiu Wang
Cc: Linux-ALSA, Timur Tabi, Xiubo Li, Liam Girdwood, Takashi Iwai,
Jaroslav Kysela, Nicolin Chen, Mark Brown, linuxppc-dev,
linux-kernel
In-Reply-To: <1600251387-1863-2-git-send-email-shengjiu.wang@nxp.com>
Hi Shengjiu,
On Wed, Sep 16, 2020 at 7:23 AM Shengjiu Wang <shengjiu.wang@nxp.com> wrote:
>
> On i.MX850/i.MX815/i.MX845 platform, the sai IP is upgraded.
Please avoid such internal SoC namings and use i.MX8MQ/i.MX8MN/iMX8MM instead.
^ permalink raw reply
* Re: [PATCH 1/3] ASoC: fsl_sai: Add new added registers and new bit definition
From: Nicolin Chen @ 2020-09-17 1:44 UTC (permalink / raw)
To: Shengjiu Wang
Cc: alsa-devel, timur, Xiubo.Lee, lgirdwood, linuxppc-dev, tiwai,
perex, broonie, festevam, linux-kernel
In-Reply-To: <1600251387-1863-2-git-send-email-shengjiu.wang@nxp.com>
On Wed, Sep 16, 2020 at 06:16:25PM +0800, Shengjiu Wang wrote:
> On i.MX850/i.MX815/i.MX845 platform, the sai IP is upgraded.
> There are some new registers and new bit definition. This
> patch is to complete the register list.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Change itself looks good.
Can add once fixing the commit message:
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
^ permalink raw reply
* Re: [PATCH 2/3] ASoC: fsl_sai: Add fsl_sai_check_version function
From: Nicolin Chen @ 2020-09-17 1:49 UTC (permalink / raw)
To: Shengjiu Wang
Cc: alsa-devel, timur, Xiubo.Lee, lgirdwood, linuxppc-dev, tiwai,
perex, broonie, festevam, linux-kernel
In-Reply-To: <1600251387-1863-3-git-send-email-shengjiu.wang@nxp.com>
On Wed, Sep 16, 2020 at 06:16:26PM +0800, Shengjiu Wang wrote:
> fsl_sai_check_version can help to parse the version info
> in VERID and PARAM registers.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> sound/soc/fsl/fsl_sai.c | 47 +++++++++++++++++++++++++++++++++++++++++
> sound/soc/fsl/fsl_sai.h | 28 ++++++++++++++++++++++++
> 2 files changed, 75 insertions(+)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 24ca528ca2be..738b4dda7847 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -946,6 +946,48 @@ static struct regmap_config fsl_sai_regmap_config = {
> .cache_type = REGCACHE_FLAT,
> };
>
> +static int fsl_sai_check_version(struct device *dev)
> +{
> + struct fsl_sai *sai = dev_get_drvdata(dev);
> + unsigned char ofs = sai->soc_data->reg_offset;
> + unsigned int val;
> + int ret;
> +
> + if (FSL_SAI_TCSR(ofs) == FSL_SAI_VERID)
> + return 0;
> +
> + ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(dev, "VERID: 0x%016X\n", val);
> +
> + sai->verid.major = (val & FSL_SAI_VERID_MAJOR_MASK) >>
> + FSL_SAI_VERID_MAJOR_SHIFT;
> + sai->verid.minor = (val & FSL_SAI_VERID_MINOR_MASK) >>
> + FSL_SAI_VERID_MINOR_SHIFT;
> + sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;
> +
> + ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(dev, "PARAM: 0x%016X\n", val);
> +
> + /* Max slots per frame, power of 2 */
> + sai->param.slot_num = 1 <<
> + ((val & FSL_SAI_PARAM_SPF_MASK) >> FSL_SAI_PARAM_SPF_SHIFT);
> +
> + /* Words per fifo, power of 2 */
> + sai->param.fifo_depth = 1 <<
> + ((val & FSL_SAI_PARAM_WPF_MASK) >> FSL_SAI_PARAM_WPF_SHIFT);
> +
> + /* Number of datalines implemented */
> + sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;
> +
> + return 0;
> +}
> +
> static int fsl_sai_probe(struct platform_device *pdev)
> {
> struct device_node *np = pdev->dev.of_node;
> @@ -1070,6 +1112,11 @@ static int fsl_sai_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, sai);
>
> + /* Get sai version */
> + ret = fsl_sai_check_version(&pdev->dev);
> + if (ret < 0)
> + dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret);
> +
> pm_runtime_enable(&pdev->dev);
> regcache_cache_only(sai->regmap, true);
>
> diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
> index d16fc4241f41..ba7425a9e217 100644
> --- a/sound/soc/fsl/fsl_sai.h
> +++ b/sound/soc/fsl/fsl_sai.h
> @@ -223,6 +223,32 @@ struct fsl_sai_soc_data {
> unsigned int reg_offset;
> };
>
> +/**
> + * struct fsl_sai_verid - version id data
> + * @major: major version number
> + * @minor: minor version number
> + * @feature: feature specification number
> + * 0000000000000000b - Standard feature set
> + * 0000000000000000b - Standard feature set
> + */
> +struct fsl_sai_verid {
> + u32 major;
> + u32 minor;
> + u32 feature;
> +};
> +
> +/**
> + * struct fsl_sai_param - parameter data
> + * @slot_num: The maximum number of slots per frame
> + * @fifo_depth: The number of words in each FIFO (depth)
> + * @dataline: The number of datalines implemented
> + */
> +struct fsl_sai_param {
> + u32 slot_num;
> + u32 fifo_depth;
> + u32 dataline;
> +};
> +
> struct fsl_sai {
> struct platform_device *pdev;
> struct regmap *regmap;
> @@ -243,6 +269,8 @@ struct fsl_sai {
> const struct fsl_sai_soc_data *soc_data;
> struct snd_dmaengine_dai_dma_data dma_params_rx;
> struct snd_dmaengine_dai_dma_data dma_params_tx;
> + struct fsl_sai_verid verid;
> + struct fsl_sai_param param;
> };
>
> #define TX 1
> --
> 2.27.0
>
^ permalink raw reply
* Re: [PATCH 3/3] ASoC: fsl_sai: Set MCLK input or output direction
From: Nicolin Chen @ 2020-09-17 1:50 UTC (permalink / raw)
To: Shengjiu Wang
Cc: alsa-devel, timur, Xiubo.Lee, lgirdwood, linuxppc-dev, tiwai,
perex, broonie, festevam, linux-kernel
In-Reply-To: <1600251387-1863-4-git-send-email-shengjiu.wang@nxp.com>
On Wed, Sep 16, 2020 at 06:16:27PM +0800, Shengjiu Wang wrote:
> SAI support select MCLK direction with version.major > 3
> and version.minor > 1, the default direction is input,
> set it to be output according to DT property.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> sound/soc/fsl/fsl_sai.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 738b4dda7847..5117c1cd5682 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -1117,6 +1117,13 @@ static int fsl_sai_probe(struct platform_device *pdev)
> if (ret < 0)
> dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret);
>
> + /* Select MCLK direction */
> + if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
> + sai->verid.major >= 3 && sai->verid.minor >= 1) {
> + regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
> + FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
> + }
> +
> pm_runtime_enable(&pdev->dev);
> regcache_cache_only(sai->regmap, true);
>
> --
> 2.27.0
>
^ permalink raw reply
* [PATCH 1/2] powerpc/64: Set up a kernel stack for secondaries before cpu_restore()
From: Jordan Niethe @ 2020-09-17 2:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe, npiggin
Currently in generic_secondary_smp_init(), cur_cpu_spec->cpu_restore()
is called before a stack has been set up in r1. This was previously fine
as the cpu_restore() functions were implemented in assembly and did not
use a stack. However commit 5a61ef74f269 ("powerpc/64s: Support new
device tree binding for discovering CPU features") used
__restore_cpu_cpufeatures() as the cpu_restore() function for a
device-tree features based cputable entry. This is a nonleaf C function
and hence requires a stack in r1.
Create the temp kernel stack before calling cpu_restore().
Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for discovering CPU features")
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
arch/powerpc/kernel/head_64.S | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 0e05a9a47a4b..4b7f4c6c2600 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -420,6 +420,10 @@ generic_secondary_common_init:
/* From now on, r24 is expected to be logical cpuid */
mr r24,r5
+ /* Create a temp kernel stack for use before relocation is on. */
+ ld r1,PACAEMERGSP(r13)
+ subi r1,r1,STACK_FRAME_OVERHEAD
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
ld r23,0(r23)
@@ -448,10 +452,6 @@ generic_secondary_common_init:
sync /* order paca.run and cur_cpu_spec */
isync /* In case code patching happened */
- /* Create a temp kernel stack for use before relocation is on. */
- ld r1,PACAEMERGSP(r13)
- subi r1,r1,STACK_FRAME_OVERHEAD
-
b __secondary_start
#endif /* SMP */
--
2.17.1
^ permalink raw reply related
* [PATCH 2/2] powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C
From: Jordan Niethe @ 2020-09-17 2:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe, npiggin
In-Reply-To: <20200917020548.20386-1-jniethe5@gmail.com>
The only thing keeping the cpu_setup() and cpu_restore() functions used
in the cputable entries for Power7, Power8, Power9 and Power10 in
assembly was cpu_restore() being called before there was a stack in
generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack
for secondaries before cpu_restore()") means that it is now possible to
use C.
Rewrite the functions in C so they are a little bit easier to read. This
is not changing their functionality.
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
arch/powerpc/include/asm/cpu_setup_power.h | 12 +
arch/powerpc/kernel/cpu_setup_power.S | 252 -------------------
arch/powerpc/kernel/cpu_setup_power.c | 269 +++++++++++++++++++++
arch/powerpc/kernel/cputable.c | 9 +-
4 files changed, 282 insertions(+), 260 deletions(-)
create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
create mode 100644 arch/powerpc/kernel/cpu_setup_power.c
diff --git a/arch/powerpc/include/asm/cpu_setup_power.h b/arch/powerpc/include/asm/cpu_setup_power.h
new file mode 100644
index 000000000000..24be9131f803
--- /dev/null
+++ b/arch/powerpc/include/asm/cpu_setup_power.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 IBM Corporation
+ */
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power7(void);
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power8(void);
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power9(void);
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
+void __restore_cpu_power10(void);
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
deleted file mode 100644
index 704e8b9501ee..000000000000
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ /dev/null
@@ -1,252 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * This file contains low level CPU setup functions.
- * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- */
-
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cache.h>
-#include <asm/book3s/64/mmu-hash.h>
-
-/* Entry: r3 = crap, r4 = ptr to cputable entry
- *
- * Note that we can be called twice for pseudo-PVRs
- */
-_GLOBAL(__setup_cpu_power7)
- mflr r11
- bl __init_hvmode_206
- mtlr r11
- beqlr
- li r0,0
- mtspr SPRN_LPID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
- bl __init_LPCR_ISA206
- mtlr r11
- blr
-
-_GLOBAL(__restore_cpu_power7)
- mflr r11
- mfmsr r3
- rldicl. r0,r3,4,63
- beqlr
- li r0,0
- mtspr SPRN_LPID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- li r4,(LPCR_LPES1 >> LPCR_LPES_SH)
- bl __init_LPCR_ISA206
- mtlr r11
- blr
-
-_GLOBAL(__setup_cpu_power8)
- mflr r11
- bl __init_FSCR
- bl __init_PMU
- bl __init_PMU_ISA207
- bl __init_hvmode_206
- mtlr r11
- beqlr
- li r0,0
- mtspr SPRN_LPID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- ori r3, r3, LPCR_PECEDH
- li r4,0 /* LPES = 0 */
- bl __init_LPCR_ISA206
- bl __init_HFSCR
- bl __init_PMU_HV
- bl __init_PMU_HV_ISA207
- mtlr r11
- blr
-
-_GLOBAL(__restore_cpu_power8)
- mflr r11
- bl __init_FSCR
- bl __init_PMU
- bl __init_PMU_ISA207
- mfmsr r3
- rldicl. r0,r3,4,63
- mtlr r11
- beqlr
- li r0,0
- mtspr SPRN_LPID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- ori r3, r3, LPCR_PECEDH
- li r4,0 /* LPES = 0 */
- bl __init_LPCR_ISA206
- bl __init_HFSCR
- bl __init_PMU_HV
- bl __init_PMU_HV_ISA207
- mtlr r11
- blr
-
-_GLOBAL(__setup_cpu_power10)
- mflr r11
- bl __init_FSCR_power10
- bl __init_PMU
- bl __init_PMU_ISA31
- b 1f
-
-_GLOBAL(__setup_cpu_power9)
- mflr r11
- bl __init_FSCR_power9
- bl __init_PMU
-1: bl __init_hvmode_206
- mtlr r11
- beqlr
- li r0,0
- mtspr SPRN_PSSCR,r0
- mtspr SPRN_LPID,r0
- mtspr SPRN_PID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
- or r3, r3, r4
- LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
- andc r3, r3, r4
- li r4,0 /* LPES = 0 */
- bl __init_LPCR_ISA300
- bl __init_HFSCR
- bl __init_PMU_HV
- mtlr r11
- blr
-
-_GLOBAL(__restore_cpu_power10)
- mflr r11
- bl __init_FSCR_power10
- bl __init_PMU
- bl __init_PMU_ISA31
- b 1f
-
-_GLOBAL(__restore_cpu_power9)
- mflr r11
- bl __init_FSCR_power9
- bl __init_PMU
-1: mfmsr r3
- rldicl. r0,r3,4,63
- mtlr r11
- beqlr
- li r0,0
- mtspr SPRN_PSSCR,r0
- mtspr SPRN_LPID,r0
- mtspr SPRN_PID,r0
- LOAD_REG_IMMEDIATE(r0, PCR_MASK)
- mtspr SPRN_PCR,r0
- mfspr r3,SPRN_LPCR
- LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
- or r3, r3, r4
- LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
- andc r3, r3, r4
- li r4,0 /* LPES = 0 */
- bl __init_LPCR_ISA300
- bl __init_HFSCR
- bl __init_PMU_HV
- mtlr r11
- blr
-
-__init_hvmode_206:
- /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
- mfmsr r3
- rldicl. r0,r3,4,63
- bnelr
- ld r5,CPU_SPEC_FEATURES(r4)
- LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST)
- andc r5,r5,r6
- std r5,CPU_SPEC_FEATURES(r4)
- blr
-
-__init_LPCR_ISA206:
- /* Setup a sane LPCR:
- * Called with initial LPCR in R3 and desired LPES 2-bit value in R4
- *
- * LPES = 0b01 (HSRR0/1 used for 0x500)
- * PECE = 0b111
- * DPFD = 4
- * HDICE = 0
- * VC = 0b100 (VPM0=1, VPM1=0, ISL=0)
- * VRMASD = 0b10000 (L=1, LP=00)
- *
- * Other bits untouched for now
- */
- li r5,0x10
- rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5
-
- /* POWER9 has no VRMASD */
-__init_LPCR_ISA300:
- rldimi r3,r4, LPCR_LPES_SH, 64-LPCR_LPES_SH-2
- ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
- li r5,4
- rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3
- clrrdi r3,r3,1 /* clear HDICE */
- li r5,4
- rldimi r3,r5, LPCR_VC_SH, 0
- mtspr SPRN_LPCR,r3
- isync
- blr
-
-__init_FSCR_power10:
- mfspr r3, SPRN_FSCR
- ori r3, r3, FSCR_PREFIX
- mtspr SPRN_FSCR, r3
- // fall through
-
-__init_FSCR_power9:
- mfspr r3, SPRN_FSCR
- ori r3, r3, FSCR_SCV
- mtspr SPRN_FSCR, r3
- // fall through
-
-__init_FSCR:
- mfspr r3,SPRN_FSCR
- ori r3,r3,FSCR_TAR|FSCR_EBB
- mtspr SPRN_FSCR,r3
- blr
-
-__init_HFSCR:
- mfspr r3,SPRN_HFSCR
- ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\
- HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP
- mtspr SPRN_HFSCR,r3
- blr
-
-__init_PMU_HV:
- li r5,0
- mtspr SPRN_MMCRC,r5
- blr
-
-__init_PMU_HV_ISA207:
- li r5,0
- mtspr SPRN_MMCRH,r5
- blr
-
-__init_PMU:
- li r5,0
- mtspr SPRN_MMCRA,r5
- mtspr SPRN_MMCR0,r5
- mtspr SPRN_MMCR1,r5
- mtspr SPRN_MMCR2,r5
- blr
-
-__init_PMU_ISA207:
- li r5,0
- mtspr SPRN_MMCRS,r5
- blr
-
-__init_PMU_ISA31:
- li r5,0
- mtspr SPRN_MMCR3,r5
- LOAD_REG_IMMEDIATE(r5, MMCRA_BHRB_DISABLE)
- mtspr SPRN_MMCRA,r5
- blr
diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c
new file mode 100644
index 000000000000..cf5201b0579d
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_power.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 IBM Corporation
+ * This file contains low level CPU setup functions.
+ * Originally written in assembly by
+ * Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ */
+#include <asm/reg.h>
+#include <asm/synch.h>
+#include <linux/bitops.h>
+#include <asm/cputable.h>
+#include <asm/cpu_setup_power.h>
+
+/* Disable CPU_FTR_HVMODE and return false if MSR:HV is not set */
+static bool init_hvmode_206(struct cpu_spec *t)
+{
+ u64 msr;
+
+ msr = mfmsr();
+ if (msr & MSR_HV)
+ return true;
+
+ t->cpu_features &= ~(CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST);
+ return false;
+}
+
+static void init_LPCR_ISA300(u64 lpcr, u64 lpes)
+{
+ /* POWER9 has no VRMASD */
+ lpcr |= (lpes << LPCR_LPES_SH) & LPCR_LPES;
+ lpcr |= LPCR_PECE0|LPCR_PECE1|LPCR_PECE2;
+ lpcr |= (4ull << LPCR_DPFD_SH) & LPCR_DPFD;
+ lpcr &= ~LPCR_HDICE; /* clear HDICE */
+ lpcr |= (4ull << LPCR_VC_SH);
+ mtspr(SPRN_LPCR, lpcr);
+ isync();
+}
+
+/*
+ * Setup a sane LPCR:
+ * Called with initial LPCR and desired LPES 2-bit value
+ *
+ * LPES = 0b01 (HSRR0/1 used for 0x500)
+ * PECE = 0b111
+ * DPFD = 4
+ * HDICE = 0
+ * VC = 0b100 (VPM0=1, VPM1=0, ISL=0)
+ * VRMASD = 0b10000 (L=1, LP=00)
+ *
+ * Other bits untouched for now
+ */
+static void init_LPCR_ISA206(u64 lpcr, u64 lpes)
+{
+ lpcr |= (0x10ull << LPCR_VRMASD_SH) & LPCR_VRMASD;
+ init_LPCR_ISA300(lpcr, lpes);
+}
+
+static void init_FSCR(void)
+{
+ u64 fscr;
+
+ fscr = mfspr(SPRN_FSCR);
+ fscr |= FSCR_TAR|FSCR_EBB;
+ mtspr(SPRN_FSCR, fscr);
+}
+
+static void init_FSCR_power9(void)
+{
+ u64 fscr;
+
+ fscr = mfspr(SPRN_FSCR);
+ fscr |= FSCR_SCV;
+ mtspr(SPRN_FSCR, fscr);
+ init_FSCR();
+}
+
+static void init_FSCR_power10(void)
+{
+ u64 fscr;
+
+ fscr = mfspr(SPRN_FSCR);
+ fscr |= FSCR_PREFIX;
+ mtspr(SPRN_FSCR, fscr);
+ init_FSCR_power9();
+}
+
+static void init_HFSCR(void)
+{
+ u64 hfscr;
+
+ hfscr = mfspr(SPRN_HFSCR);
+ hfscr |= HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|HFSCR_DSCR|\
+ HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP;
+ mtspr(SPRN_HFSCR, hfscr);
+}
+
+static void init_PMU_HV(void)
+{
+ mtspr(SPRN_MMCRC, 0);
+}
+
+static void init_PMU_HV_ISA207(void)
+{
+ mtspr(SPRN_MMCRH, 0);
+}
+
+static void init_PMU(void)
+{
+ mtspr(SPRN_MMCRA, 0);
+ mtspr(SPRN_MMCR0, 0);
+ mtspr(SPRN_MMCR1, 0);
+ mtspr(SPRN_MMCR2, 0);
+}
+
+static void init_PMU_ISA207(void)
+{
+ mtspr(SPRN_MMCRS, 0);
+}
+
+static void init_PMU_ISA31(void)
+{
+ mtspr(SPRN_MMCR3, 0);
+ mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE);
+}
+
+/*
+ * Note that we can be called twice of pseudo-PVRs.
+ * The parameter offset is not used.
+ */
+
+void __setup_cpu_power7(unsigned long offset, struct cpu_spec *t)
+{
+ if (!init_hvmode_206(t))
+ return;
+
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH);
+}
+
+void __restore_cpu_power7(void)
+{
+ u64 msr;
+
+ msr = mfmsr();
+ if (!(msr & MSR_HV))
+ return;
+
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH);
+}
+
+void __setup_cpu_power8(unsigned long offset, struct cpu_spec *t)
+{
+ init_FSCR();
+ init_PMU();
+ init_PMU_ISA207();
+
+ if (!init_hvmode_206(t))
+ return;
+
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */
+ init_HFSCR();
+ init_PMU_HV();
+ init_PMU_HV_ISA207();
+}
+
+void __restore_cpu_power8(void)
+{
+ u64 msr;
+
+ init_FSCR();
+ init_PMU();
+ init_PMU_ISA207();
+
+ msr = mfmsr();
+ if (!(msr & MSR_HV))
+ return;
+
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */
+ init_HFSCR();
+ init_PMU_HV();
+ init_PMU_HV_ISA207();
+}
+
+void __setup_cpu_power9(unsigned long offset, struct cpu_spec *t)
+{
+ init_FSCR_power9();
+ init_PMU();
+
+ if (!init_hvmode_206(t))
+ return;
+
+ mtspr(SPRN_PSSCR, 0);
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
+ LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
+ init_HFSCR();
+ init_PMU_HV();
+}
+
+void __restore_cpu_power9(void)
+{
+ u64 msr;
+
+ init_FSCR_power9();
+ init_PMU();
+
+ msr = mfmsr();
+ if (!(msr & MSR_HV))
+ return;
+
+ mtspr(SPRN_PSSCR, 0);
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
+ LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
+ init_HFSCR();
+ init_PMU_HV();
+}
+
+void __setup_cpu_power10(unsigned long offset, struct cpu_spec *t)
+{
+ init_FSCR_power10();
+ init_PMU();
+ init_PMU_ISA31();
+
+ if (!init_hvmode_206(t))
+ return;
+
+ mtspr(SPRN_PSSCR, 0);
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
+ LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
+ init_HFSCR();
+ init_PMU_HV();
+}
+
+void __restore_cpu_power10(void)
+{
+ u64 msr;
+
+ init_FSCR_power10();
+ init_PMU();
+ init_PMU_ISA31();
+
+ msr = mfmsr();
+ if (!(msr & MSR_HV))
+ return;
+
+ mtspr(SPRN_PSSCR, 0);
+ mtspr(SPRN_LPID, 0);
+ mtspr(SPRN_PID, 0);
+ mtspr(SPRN_PCR, PCR_MASK);
+ init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
+ LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
+ init_HFSCR();
+ init_PMU_HV();
+}
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 3d406a9626e8..bce545280056 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -59,19 +59,12 @@ extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
#endif /* CONFIG_PPC32 */
#ifdef CONFIG_PPC64
+#include <asm/cpu_setup_power.h>
extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
extern void __restore_cpu_pa6t(void);
extern void __restore_cpu_ppc970(void);
-extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
-extern void __restore_cpu_power7(void);
-extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
-extern void __restore_cpu_power8(void);
-extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec);
-extern void __restore_cpu_power9(void);
-extern void __setup_cpu_power10(unsigned long offset, struct cpu_spec* spec);
-extern void __restore_cpu_power10(void);
extern long __machine_check_early_realmode_p7(struct pt_regs *regs);
extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
--
2.17.1
^ permalink raw reply related
* [PATCH -next v2] powerpc/book3s64: fix link error with CONFIG_PPC_RADIX_MMU=n
From: Yang Yingliang @ 2020-09-17 2:06 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: yangyingliang
Fix link error when CONFIG_PPC_RADIX_MMU is disabled:
powerpc64-linux-gnu-ld: arch/powerpc/platforms/pseries/lpar.o:(.toc+0x0): undefined reference to `mmu_pid_bits'
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
v2:
- enclose radix_init_pseries with CONFIG_PPC_RADIX_MMU
- remove CONFIG_PPC_RADIX_MMU in radix__init_new_context()
---
arch/powerpc/platforms/pseries/lpar.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index baf24eacd268..764170fdb0f7 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1724,6 +1724,7 @@ void __init hpte_init_pseries(void)
pseries_lpar_register_process_table(0, 0, 0);
}
+#ifdef CONFIG_PPC_RADIX_MMU
void radix_init_pseries(void)
{
pr_info("Using radix MMU under hypervisor\n");
@@ -1731,6 +1732,7 @@ void radix_init_pseries(void)
pseries_lpar_register_process_table(__pa(process_tb),
0, PRTB_SIZE_SHIFT - 12);
}
+#endif
#ifdef CONFIG_PPC_SMLPAR
#define CMO_FREE_HINT_DEFAULT 1
--
2.25.1
^ permalink raw reply related
* [PATCH] powerpc/process: Fix uninitialised variable error
From: Michael Ellerman @ 2020-09-17 2:45 UTC (permalink / raw)
To: linuxppc-dev
Clang, and GCC with -Wmaybe-uninitialized, can't see that val is
unused in get_fpexec_mode():
arch/powerpc/kernel/process.c:1940:7: error: variable 'val' is used
uninitialized whenever 'if' condition is true
if (cpu_has_feature(CPU_FTR_SPE)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
We know that CPU_FTR_SPE will only be true iff CONFIG_SPE is also
true, but the compiler doesn't.
Avoid it by initialising val to zero.
Reported-by: kernel test robot <lkp@intel.com>
Fixes: 532ed1900d37 ("powerpc/process: Remove useless #ifdef CONFIG_SPE")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/kernel/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 14d5189b17d8..d421a2c7f822 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1934,7 +1934,7 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
{
- unsigned int val;
+ unsigned int val = 0;
if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) {
if (cpu_has_feature(CPU_FTR_SPE)) {
--
2.25.1
^ permalink raw reply related
* Re: [PATCH 2/2] powerpc/perf: Add declarations to fix sparse warnings
From: Madhavan Srinivasan @ 2020-09-17 4:30 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev
In-Reply-To: <20200916115637.3100484-2-mpe@ellerman.id.au>
On 9/16/20 5:26 PM, Michael Ellerman wrote:
> Sparse warns about all the init functions:
> symbol init_ppc970_pmu was not declared. Should it be static?
> symbol init_power5p_pmu was not declared. Should it be static?
> symbol init_power5_pmu was not declared. Should it be static?
> symbol init_power6_pmu was not declared. Should it be static?
> symbol init_power7_pmu was not declared. Should it be static?
> symbol init_power9_pmu was not declared. Should it be static?
> symbol init_power8_pmu was not declared. Should it be static?
> symbol init_generic_compat_pmu was not declared. Should it be static?
>
> They're already declared in internal.h, so just make sure all the C
> files include that directly or indirectly.
Reviewed-by: Madhavan Srinivasan <maddy@linux.ibm.com>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/perf/isa207-common.h | 2 ++
> arch/powerpc/perf/power10-pmu.c | 1 -
> arch/powerpc/perf/power5+-pmu.c | 2 ++
> arch/powerpc/perf/power5-pmu.c | 2 ++
> arch/powerpc/perf/power6-pmu.c | 2 ++
> arch/powerpc/perf/power7-pmu.c | 2 ++
> arch/powerpc/perf/ppc970-pmu.c | 2 ++
> 7 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h
> index 044de65e96b9..7025de5e60e7 100644
> --- a/arch/powerpc/perf/isa207-common.h
> +++ b/arch/powerpc/perf/isa207-common.h
> @@ -13,6 +13,8 @@
> #include <asm/firmware.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> #define EVENT_EBB_MASK 1ull
> #define EVENT_EBB_SHIFT PERF_EVENT_CONFIG_EBB_SHIFT
> #define EVENT_BHRB_MASK 1ull
> diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c
> index 83148656b524..9dbe8f9b89b4 100644
> --- a/arch/powerpc/perf/power10-pmu.c
> +++ b/arch/powerpc/perf/power10-pmu.c
> @@ -9,7 +9,6 @@
> #define pr_fmt(fmt) "power10-pmu: " fmt
>
> #include "isa207-common.h"
> -#include "internal.h"
>
> /*
> * Raw event encoding for Power10:
> diff --git a/arch/powerpc/perf/power5+-pmu.c b/arch/powerpc/perf/power5+-pmu.c
> index a62b2cd7914f..3e64b4a1511f 100644
> --- a/arch/powerpc/perf/power5+-pmu.c
> +++ b/arch/powerpc/perf/power5+-pmu.c
> @@ -10,6 +10,8 @@
> #include <asm/reg.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> /*
> * Bits in event code for POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3)
> */
> diff --git a/arch/powerpc/perf/power5-pmu.c b/arch/powerpc/perf/power5-pmu.c
> index 8732b587cf71..017bb19b73fb 100644
> --- a/arch/powerpc/perf/power5-pmu.c
> +++ b/arch/powerpc/perf/power5-pmu.c
> @@ -10,6 +10,8 @@
> #include <asm/reg.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> /*
> * Bits in event code for POWER5 (not POWER5++)
> */
> diff --git a/arch/powerpc/perf/power6-pmu.c b/arch/powerpc/perf/power6-pmu.c
> index 0e318cf87129..189974478e9f 100644
> --- a/arch/powerpc/perf/power6-pmu.c
> +++ b/arch/powerpc/perf/power6-pmu.c
> @@ -10,6 +10,8 @@
> #include <asm/reg.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> /*
> * Bits in event code for POWER6
> */
> diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
> index 5e0bf09cf077..bacfab104a1a 100644
> --- a/arch/powerpc/perf/power7-pmu.c
> +++ b/arch/powerpc/perf/power7-pmu.c
> @@ -10,6 +10,8 @@
> #include <asm/reg.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> /*
> * Bits in event code for POWER7
> */
> diff --git a/arch/powerpc/perf/ppc970-pmu.c b/arch/powerpc/perf/ppc970-pmu.c
> index d35223fb112c..7d78df97f272 100644
> --- a/arch/powerpc/perf/ppc970-pmu.c
> +++ b/arch/powerpc/perf/ppc970-pmu.c
> @@ -9,6 +9,8 @@
> #include <asm/reg.h>
> #include <asm/cputable.h>
>
> +#include "internal.h"
> +
> /*
> * Bits in event code for PPC970
> */
^ permalink raw reply
* [PATCH v2 0/3] ASoC: fsl_sai: update the register list
From: Shengjiu Wang @ 2020-09-17 6:11 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood
Cc: linuxppc-dev, linux-kernel
As sai ip is upgraded, so update sai register list.
Shengjiu Wang (3):
ASoC: fsl_sai: Add new added registers and new bit definition
ASoC: fsl_sai: Add fsl_sai_check_version function
ASoC: fsl_sai: Set MCLK input or output direction
changes in v2:
- update commit message for first commit
- Add acked-by Nicolin
sound/soc/fsl/fsl_sai.c | 77 ++++++++++++++++++++++++++++++++++++
sound/soc/fsl/fsl_sai.h | 87 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+)
--
2.27.0
^ permalink raw reply
* [PATCH v2 1/3] ASoC: fsl_sai: Add new added registers and new bit definition
From: Shengjiu Wang @ 2020-09-17 6:11 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1600323079-5317-1-git-send-email-shengjiu.wang@nxp.com>
On i.MX8MQ/i.MX8MN/i.MX8MM platform, the sai IP is upgraded.
There are some new registers and new bit definition. This
patch is to complete the register list.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_sai.c | 23 ++++++++++++++++
sound/soc/fsl/fsl_sai.h | 59 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index b2d65e53dbc4..24ca528ca2be 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -796,6 +796,8 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = {
{FSL_SAI_RCR4(8), 0},
{FSL_SAI_RCR5(8), 0},
{FSL_SAI_RMR, 0},
+ {FSL_SAI_MCTL, 0},
+ {FSL_SAI_MDIV, 0},
};
static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
@@ -836,6 +838,18 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
case FSL_SAI_RFR6:
case FSL_SAI_RFR7:
case FSL_SAI_RMR:
+ case FSL_SAI_MCTL:
+ case FSL_SAI_MDIV:
+ case FSL_SAI_VERID:
+ case FSL_SAI_PARAM:
+ case FSL_SAI_TTCTN:
+ case FSL_SAI_RTCTN:
+ case FSL_SAI_TTCTL:
+ case FSL_SAI_TBCTN:
+ case FSL_SAI_TTCAP:
+ case FSL_SAI_RTCTL:
+ case FSL_SAI_RBCTN:
+ case FSL_SAI_RTCAP:
return true;
default:
return false;
@@ -850,6 +864,10 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs))
return true;
+ /* Set VERID and PARAM be volatile for reading value in probe */
+ if (ofs == 8 && (reg == FSL_SAI_VERID || reg == FSL_SAI_PARAM))
+ return true;
+
switch (reg) {
case FSL_SAI_TFR0:
case FSL_SAI_TFR1:
@@ -903,6 +921,10 @@ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
case FSL_SAI_TDR7:
case FSL_SAI_TMR:
case FSL_SAI_RMR:
+ case FSL_SAI_MCTL:
+ case FSL_SAI_MDIV:
+ case FSL_SAI_TTCTL:
+ case FSL_SAI_RTCTL:
return true;
default:
return false;
@@ -951,6 +973,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
if (sai->soc_data->reg_offset == 8) {
fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8;
+ fsl_sai_regmap_config.max_register = FSL_SAI_MDIV;
fsl_sai_regmap_config.num_reg_defaults =
ARRAY_SIZE(fsl_sai_reg_defaults_ofs8);
}
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 736a437450c8..d16fc4241f41 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -14,6 +14,8 @@
SNDRV_PCM_FMTBIT_S32_LE)
/* SAI Register Map Register */
+#define FSL_SAI_VERID 0x00 /* SAI Version ID Register */
+#define FSL_SAI_PARAM 0x04 /* SAI Parameter Register */
#define FSL_SAI_TCSR(ofs) (0x00 + ofs) /* SAI Transmit Control */
#define FSL_SAI_TCR1(ofs) (0x04 + ofs) /* SAI Transmit Configuration 1 */
#define FSL_SAI_TCR2(ofs) (0x08 + ofs) /* SAI Transmit Configuration 2 */
@@ -37,6 +39,10 @@
#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_TTCTL 0x70 /* SAI Transmit Timestamp Control Register */
+#define FSL_SAI_TTCTN 0x74 /* SAI Transmit Timestamp Counter Register */
+#define FSL_SAI_TBCTN 0x78 /* SAI Transmit Bit Counter Register */
+#define FSL_SAI_TTCAP 0x7C /* SAI Transmit Timestamp Capture */
#define FSL_SAI_RCSR(ofs) (0x80 + ofs) /* SAI Receive Control */
#define FSL_SAI_RCR1(ofs) (0x84 + ofs)/* SAI Receive Configuration 1 */
#define FSL_SAI_RCR2(ofs) (0x88 + ofs) /* SAI Receive Configuration 2 */
@@ -60,6 +66,13 @@
#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_RTCTL 0xf0 /* SAI Receive Timestamp Control Register */
+#define FSL_SAI_RTCTN 0xf4 /* SAI Receive Timestamp Counter Register */
+#define FSL_SAI_RBCTN 0xf8 /* SAI Receive Bit Counter Register */
+#define FSL_SAI_RTCAP 0xfc /* SAI Receive Timestamp Capture */
+
+#define FSL_SAI_MCTL 0x100 /* SAI MCLK Control Register */
+#define FSL_SAI_MDIV 0x104 /* SAI MCLK Divide Register */
#define FSL_SAI_xCSR(tx, ofs) (tx ? FSL_SAI_TCSR(ofs) : FSL_SAI_RCSR(ofs))
#define FSL_SAI_xCR1(tx, ofs) (tx ? FSL_SAI_TCR1(ofs) : FSL_SAI_RCR1(ofs))
@@ -73,6 +86,7 @@
/* SAI Transmit/Receive Control Register */
#define FSL_SAI_CSR_TERE BIT(31)
+#define FSL_SAI_CSR_SE BIT(30)
#define FSL_SAI_CSR_FR BIT(25)
#define FSL_SAI_CSR_SR BIT(24)
#define FSL_SAI_CSR_xF_SHIFT 16
@@ -106,6 +120,7 @@
#define FSL_SAI_CR2_MSEL(ID) ((ID) << 26)
#define FSL_SAI_CR2_BCP BIT(25)
#define FSL_SAI_CR2_BCD_MSTR BIT(24)
+#define FSL_SAI_CR2_BYP BIT(23) /* BCLK bypass */
#define FSL_SAI_CR2_DIV_MASK 0xff
/* SAI Transmit and Receive Configuration 3 Register */
@@ -115,6 +130,13 @@
#define FSL_SAI_CR3_WDFL_MASK 0x1f
/* SAI Transmit and Receive Configuration 4 Register */
+
+#define FSL_SAI_CR4_FCONT BIT(28)
+#define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
+#define FSL_SAI_CR4_FCOMB_SOFT BIT(27)
+#define FSL_SAI_CR4_FCOMB_MASK (0x3 << 26)
+#define FSL_SAI_CR4_FPACK_8 (0x2 << 24)
+#define FSL_SAI_CR4_FPACK_16 (0x3 << 24)
#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
@@ -134,6 +156,43 @@
#define FSL_SAI_CR5_FBT(x) ((x) << 8)
#define FSL_SAI_CR5_FBT_MASK (0x1f << 8)
+/* SAI MCLK Control Register */
+#define FSL_SAI_MCTL_MCLK_EN BIT(30) /* MCLK Enable */
+#define FSL_SAI_MCTL_MSEL_MASK (0x3 << 24)
+#define FSL_SAI_MCTL_MSEL(ID) ((ID) << 24)
+#define FSL_SAI_MCTL_MSEL_BUS 0
+#define FSL_SAI_MCTL_MSEL_MCLK1 BIT(24)
+#define FSL_SAI_MCTL_MSEL_MCLK2 BIT(25)
+#define FSL_SAI_MCTL_MSEL_MCLK3 (BIT(24) | BIT(25))
+#define FSL_SAI_MCTL_DIV_EN BIT(23)
+#define FSL_SAI_MCTL_DIV_MASK 0xFF
+
+/* SAI VERID Register */
+#define FSL_SAI_VERID_MAJOR_SHIFT 24
+#define FSL_SAI_VERID_MAJOR_MASK GENMASK(31, 24)
+#define FSL_SAI_VERID_MINOR_SHIFT 16
+#define FSL_SAI_VERID_MINOR_MASK GENMASK(23, 16)
+#define FSL_SAI_VERID_FEATURE_SHIFT 0
+#define FSL_SAI_VERID_FEATURE_MASK GENMASK(15, 0)
+#define FSL_SAI_VERID_EFIFO_EN BIT(0)
+#define FSL_SAI_VERID_TSTMP_EN BIT(1)
+
+/* SAI PARAM Register */
+#define FSL_SAI_PARAM_SPF_SHIFT 16
+#define FSL_SAI_PARAM_SPF_MASK GENMASK(19, 16)
+#define FSL_SAI_PARAM_WPF_SHIFT 8
+#define FSL_SAI_PARAM_WPF_MASK GENMASK(11, 8)
+#define FSL_SAI_PARAM_DLN_MASK GENMASK(3, 0)
+
+/* SAI MCLK Divide Register */
+#define FSL_SAI_MDIV_MASK 0xFFFFF
+
+/* SAI timestamp and bitcounter */
+#define FSL_SAI_xTCTL_TSEN BIT(0)
+#define FSL_SAI_xTCTL_TSINC BIT(1)
+#define FSL_SAI_xTCTL_RTSC BIT(8)
+#define FSL_SAI_xTCTL_RBC BIT(9)
+
/* SAI type */
#define FSL_SAI_DMA BIT(0)
#define FSL_SAI_USE_AC97 BIT(1)
--
2.27.0
^ permalink raw reply related
* [PATCH v2 2/3] ASoC: fsl_sai: Add fsl_sai_check_version function
From: Shengjiu Wang @ 2020-09-17 6:11 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1600323079-5317-1-git-send-email-shengjiu.wang@nxp.com>
fsl_sai_check_version can help to parse the version info
in VERID and PARAM registers.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_sai.c | 47 +++++++++++++++++++++++++++++++++++++++++
sound/soc/fsl/fsl_sai.h | 28 ++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 24ca528ca2be..738b4dda7847 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -946,6 +946,48 @@ static struct regmap_config fsl_sai_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
+static int fsl_sai_check_version(struct device *dev)
+{
+ struct fsl_sai *sai = dev_get_drvdata(dev);
+ unsigned char ofs = sai->soc_data->reg_offset;
+ unsigned int val;
+ int ret;
+
+ if (FSL_SAI_TCSR(ofs) == FSL_SAI_VERID)
+ return 0;
+
+ ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(dev, "VERID: 0x%016X\n", val);
+
+ sai->verid.major = (val & FSL_SAI_VERID_MAJOR_MASK) >>
+ FSL_SAI_VERID_MAJOR_SHIFT;
+ sai->verid.minor = (val & FSL_SAI_VERID_MINOR_MASK) >>
+ FSL_SAI_VERID_MINOR_SHIFT;
+ sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;
+
+ ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(dev, "PARAM: 0x%016X\n", val);
+
+ /* Max slots per frame, power of 2 */
+ sai->param.slot_num = 1 <<
+ ((val & FSL_SAI_PARAM_SPF_MASK) >> FSL_SAI_PARAM_SPF_SHIFT);
+
+ /* Words per fifo, power of 2 */
+ sai->param.fifo_depth = 1 <<
+ ((val & FSL_SAI_PARAM_WPF_MASK) >> FSL_SAI_PARAM_WPF_SHIFT);
+
+ /* Number of datalines implemented */
+ sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;
+
+ return 0;
+}
+
static int fsl_sai_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -1070,6 +1112,11 @@ static int fsl_sai_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sai);
+ /* Get sai version */
+ ret = fsl_sai_check_version(&pdev->dev);
+ if (ret < 0)
+ dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret);
+
pm_runtime_enable(&pdev->dev);
regcache_cache_only(sai->regmap, true);
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index d16fc4241f41..ba7425a9e217 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -223,6 +223,32 @@ struct fsl_sai_soc_data {
unsigned int reg_offset;
};
+/**
+ * struct fsl_sai_verid - version id data
+ * @major: major version number
+ * @minor: minor version number
+ * @feature: feature specification number
+ * 0000000000000000b - Standard feature set
+ * 0000000000000000b - Standard feature set
+ */
+struct fsl_sai_verid {
+ u32 major;
+ u32 minor;
+ u32 feature;
+};
+
+/**
+ * struct fsl_sai_param - parameter data
+ * @slot_num: The maximum number of slots per frame
+ * @fifo_depth: The number of words in each FIFO (depth)
+ * @dataline: The number of datalines implemented
+ */
+struct fsl_sai_param {
+ u32 slot_num;
+ u32 fifo_depth;
+ u32 dataline;
+};
+
struct fsl_sai {
struct platform_device *pdev;
struct regmap *regmap;
@@ -243,6 +269,8 @@ struct fsl_sai {
const struct fsl_sai_soc_data *soc_data;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
+ struct fsl_sai_verid verid;
+ struct fsl_sai_param param;
};
#define TX 1
--
2.27.0
^ permalink raw reply related
* [PATCH v2 3/3] ASoC: fsl_sai: Set MCLK input or output direction
From: Shengjiu Wang @ 2020-09-17 6:11 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1600323079-5317-1-git-send-email-shengjiu.wang@nxp.com>
SAI support select MCLK direction with version.major > 3
and version.minor > 1, the default direction is input,
set it to be output according to DT property.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_sai.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 738b4dda7847..5117c1cd5682 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1117,6 +1117,13 @@ static int fsl_sai_probe(struct platform_device *pdev)
if (ret < 0)
dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret);
+ /* Select MCLK direction */
+ if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+ sai->verid.major >= 3 && sai->verid.minor >= 1) {
+ regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
+ FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
+ }
+
pm_runtime_enable(&pdev->dev);
regcache_cache_only(sai->regmap, true);
--
2.27.0
^ permalink raw reply related
* Re: [PATCH 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
From: Nicolin Chen @ 2020-09-17 7:14 UTC (permalink / raw)
To: Viorel Suman (OSS)
Cc: devicetree, alsa-devel, Matthias Schiffer, Viorel Suman,
Timur Tabi, Xiubo Li, Shengjiu Wang, linuxppc-dev, Takashi Iwai,
Rob Herring, Liam Girdwood, Viorel Suman, Mark Brown,
NXP Linux Team, Philipp Zabel, Cosmin-Gabriel Samoila,
Jaroslav Kysela, Fabio Estevam, linux-kernel
In-Reply-To: <1600247876-8013-2-git-send-email-viorel.suman@oss.nxp.com>
Hi Viorel,
It looks pretty clean to me, though some small comments inline.
On Wed, Sep 16, 2020 at 12:17:55PM +0300, Viorel Suman (OSS) wrote:
> From: Viorel Suman <viorel.suman@nxp.com>
>
> XCVR (Audio Transceiver) is a on-chip functional module found
> on i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.
>
> Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
> +static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, }; /* one bit 6, 12 ? */
What's the meaning of the comments?
> +static const int fsl_xcvr_phy_arc_cfg[] = {
> + FSL_XCVR_PHY_CTRL_ARC_MODE_SE_EN, FSL_XCVR_PHY_CTRL_ARC_MODE_CM_EN,
> +};
Nit: better be u32 vs. int?
> +/** phy: true => phy, false => pll */
> +static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
> +{
> + u32 val, idx, tidx;
> +
> + idx = BIT(phy ? 26 : 24);
> + tidx = BIT(phy ? 27 : 25);
> +
> + regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF);
> + regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg);
> + regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_WDATA, data);
> + regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
> +
> + do {
> + regmap_read(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, &val);
> + } while ((val & idx) != ((val & tidx) >> 1));
Might regmap_read_poll_timeout() be better? And it seems to poll
intentionally with no sleep nor timeout -- would be nice to have
a line of comments to explain why.
> > +static int fsl_xcvr_runtime_resume(struct device *dev)
> +{
> + struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
> + int ret;
> +
> + ret = clk_prepare_enable(xcvr->ipg_clk);
> + if (ret) {
> + dev_err(dev, "failed to start IPG clock.\n");
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(xcvr->pll_ipg_clk);
> + if (ret) {
> + dev_err(dev, "failed to start PLL IPG clock.\n");
Should it disable ipg_clk?
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(xcvr->phy_clk);
> + if (ret) {
> + dev_err(dev, "failed to start PHY clock: %d\n", ret);
> + clk_disable_unprepare(xcvr->ipg_clk);
Should it disable pll_ipg_clk?
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(xcvr->spba_clk);
> + if (ret) {
> + dev_err(dev, "failed to start SPBA clock.\n");
> + clk_disable_unprepare(xcvr->phy_clk);
> + clk_disable_unprepare(xcvr->ipg_clk);
Ditto
> + return ret;
> + }
> +
> + regcache_cache_only(xcvr->regmap, false);
> + regcache_mark_dirty(xcvr->regmap);
> + ret = regcache_sync(xcvr->regmap);
> +
> + if (ret) {
> + dev_err(dev, "failed to sync regcache.\n");
> + return ret;
What about those clocks? Probably better to have some error-out
labels at the end of the function?
> + }
> +
> + reset_control_assert(xcvr->reset);
> + reset_control_deassert(xcvr->reset);
> +
> + ret = fsl_xcvr_load_firmware(xcvr);
> + if (ret) {
> + dev_err(dev, "failed to load firmware.\n");
> + return ret;
Ditto
> + }
> +
> + /* Release M0+ reset */
> + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
> + FSL_XCVR_EXT_CTRL_CORE_RESET, 0);
> + if (ret < 0) {
> + dev_err(dev, "M0+ core release failed: %d\n", ret);
> + return ret;
Ditto
> + }
> + mdelay(50);
Any reason to use mdelay over msleep for a 50ms wait? May add a
line of comments if mdelay is a must?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox