* Re: [PATCHv1 0/3] Enable RTC on Odroid N2
From: Kevin Hilman @ 2020-07-16 21:28 UTC (permalink / raw)
To: Neil Armstrong, Anand Moon
Cc: Mark Rutland, devicetree, Martin Blumenstingl, Rob Herring,
linux-amlogic, linux-arm-kernel, Jerome Brunet
In-Reply-To: <a7e9b154-ceb2-3915-454a-a53c9b65622e@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> Hi,
>
> On 16/07/2020 10:20, Neil Armstrong wrote:
>> Hi,
>>
>> On 16/07/2020 10:14, Anand Moon wrote:
>>> Hi Neil,
>>>
>>> Thanks for your review comments.
>>>
>>> On Thu, 16 Jul 2020 at 12:35, Neil Armstrong <narmstrong@baylibre.com> wrote:
>>>>
>>>> Hi Anand,
>>>>
>>>> Only the vrtc is able to wakeup the device from suspend,
>>>> the external RTC is not capable.
>>>>
>>>> Neil
>>>
>>> Now I have two RTC driver registered
>>>
>>> $ dmesg | grep rtc
>>> [ 4.737315] rtc-pcf8563 0-0051: registered as rtc0
>>> [ 4.738763] rtc-pcf8563 0-0051: setting system clock to
>>> 2020-07-16T08:00:46 UTC (1594886446)
>>> [ 4.790206] meson-vrtc ff8000a8.rtc: registered as rtc1
>>>
>>> And there are two nodes
>>> # ls /dev/rtc*
>>> /dev/rtc /dev/rtc0 /dev/rtc1
>>>
>>> So it seames an issue that /dev/rtc0 is not able to handle wakeup events.
>>> How can we resolve this issue?
>>>
>>> # time rtcwake -s 30 -m mem
>>> rtcwake: /dev/rtc0 not enabled for wakeup events
>>
>> rtcwake -d /dev/rtc1 -s 30 -m mem
>>
>> As Christian reported off-list, it may be necessary to keep the vrtc as rtc0,
>> so you should add aliases in the odroid-n2 DT to have vrtc as rtc0 and the on-board
>> rtc as rtc1, but it may break the hwclock tools, so the reverse may be better
>> but you'll need to specify rtc1 to rtcwake.
>
> While looking closer to the Odroid-N2 schematics and U-Boot/SCP Firmware, the external on-board
> RTC can wake the device with the GPIO_AO 7, and wakeup is enabled in:
> https://github.com/hardkernel/u-boot/blob/odroidn2-v2015.01/board/hardkernel/odroidn2/firmware/scp_task/pwr_ctrl.c#L143
>
> So, something must be missing.
A couple possibilities come to mind (without looking at the specific RTC
driver):
1) pinctrl for that GPIO needs proper settings
2) DT node for the RTC needs "wakeup-source" property
Kevin
_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: pinctrl: qcom: Add msm8226 pinctrl bindings
From: Bartosz Dudziak @ 2020-07-16 21:29 UTC (permalink / raw)
To: Rob Herring
Cc: Bjorn Andersson, Andy Gross, Linus Walleij, linux-arm-msm,
linux-gpio, devicetree, linux-kernel
In-Reply-To: <20200715202413.GA755488@bogus>
On Wed, Jul 15, 2020 at 02:24:13PM -0600, Rob Herring wrote:
> On Sat, Jun 27, 2020 at 09:28:30PM +0200, Bartosz Dudziak wrote:
> > Add device tree binding Documentation details for Qualcomm msm8226
> > pinctrl driver.
> >
> > - Bindings documentation was based on qcom,sm8250-pinctrl.yaml by
> > Bjorn Andersson <bjorn.andersson@linaro.org> and then modified for
> > msm8226 content
> >
> > Signed-off-by: Bartosz Dudziak <bartosz.dudziak@snejp.pl>
> > ---
> > .../pinctrl/qcom,msm8226-pinctrl.yaml | 123 ++++++++++++++++++
> > 1 file changed, 123 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,msm8226-pinctrl.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8226-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,msm8226-pinctrl.yaml
> > new file mode 100644
> > index 0000000000..8d8dc15718
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8226-pinctrl.yaml
> > @@ -0,0 +1,123 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pinctrl/qcom,msm8226-pinctrl.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Qualcomm Technologies, Inc. MSM8226 TLMM block
> > +
> > +maintainers:
> > + - Bjorn Andersson <bjorn.andersson@linaro.org>
> > +
> > +description: |
> > + This binding describes the Top Level Mode Multiplexer block found in the
> > + MSM8226 platform.
> > +
> > +properties:
> > + compatible:
> > + const: qcom,msm8226-pinctrl
> > +
> > + reg:
> > + description: Specifies the base address and size of the TLMM register space
> > + maxItems: 1
> > +
> > + interrupts:
> > + description: Specifies the TLMM summary IRQ
> > + maxItems: 1
> > +
> > + interrupt-controller: true
> > +
> > + '#interrupt-cells':
> > + description: Specifies the PIN numbers and Flags, as defined in
> > + include/dt-bindings/interrupt-controller/irq.h
> > + const: 2
> > +
> > + gpio-controller: true
> > +
> > + '#gpio-cells':
> > + description: Specifying the pin number and flags, as defined in
> > + include/dt-bindings/gpio/gpio.h
> > + const: 2
> > +
> > + gpio-ranges:
> > + maxItems: 1
> > +
> > + gpio-reserved-ranges:
> > + maxItems: 1
> > +
> > +#PIN CONFIGURATION NODES
> > +patternProperties:
> > + '^.*$':
> > + if:
> > + type: object
>
> For new bindings, do '-pins$' for the node name pattern so we don't have
> to do this hack.
>
I have changed the name pattern and sent a v2 patch.
^ permalink raw reply
* Re: [PATCHv1 0/3] Enable RTC on Odroid N2
From: Kevin Hilman @ 2020-07-16 21:28 UTC (permalink / raw)
To: Neil Armstrong, Anand Moon
Cc: devicetree, linux-arm-kernel, linux-amlogic, Rob Herring,
Mark Rutland, Martin Blumenstingl, Jerome Brunet
In-Reply-To: <a7e9b154-ceb2-3915-454a-a53c9b65622e@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> Hi,
>
> On 16/07/2020 10:20, Neil Armstrong wrote:
>> Hi,
>>
>> On 16/07/2020 10:14, Anand Moon wrote:
>>> Hi Neil,
>>>
>>> Thanks for your review comments.
>>>
>>> On Thu, 16 Jul 2020 at 12:35, Neil Armstrong <narmstrong@baylibre.com> wrote:
>>>>
>>>> Hi Anand,
>>>>
>>>> Only the vrtc is able to wakeup the device from suspend,
>>>> the external RTC is not capable.
>>>>
>>>> Neil
>>>
>>> Now I have two RTC driver registered
>>>
>>> $ dmesg | grep rtc
>>> [ 4.737315] rtc-pcf8563 0-0051: registered as rtc0
>>> [ 4.738763] rtc-pcf8563 0-0051: setting system clock to
>>> 2020-07-16T08:00:46 UTC (1594886446)
>>> [ 4.790206] meson-vrtc ff8000a8.rtc: registered as rtc1
>>>
>>> And there are two nodes
>>> # ls /dev/rtc*
>>> /dev/rtc /dev/rtc0 /dev/rtc1
>>>
>>> So it seames an issue that /dev/rtc0 is not able to handle wakeup events.
>>> How can we resolve this issue?
>>>
>>> # time rtcwake -s 30 -m mem
>>> rtcwake: /dev/rtc0 not enabled for wakeup events
>>
>> rtcwake -d /dev/rtc1 -s 30 -m mem
>>
>> As Christian reported off-list, it may be necessary to keep the vrtc as rtc0,
>> so you should add aliases in the odroid-n2 DT to have vrtc as rtc0 and the on-board
>> rtc as rtc1, but it may break the hwclock tools, so the reverse may be better
>> but you'll need to specify rtc1 to rtcwake.
>
> While looking closer to the Odroid-N2 schematics and U-Boot/SCP Firmware, the external on-board
> RTC can wake the device with the GPIO_AO 7, and wakeup is enabled in:
> https://github.com/hardkernel/u-boot/blob/odroidn2-v2015.01/board/hardkernel/odroidn2/firmware/scp_task/pwr_ctrl.c#L143
>
> So, something must be missing.
A couple possibilities come to mind (without looking at the specific RTC
driver):
1) pinctrl for that GPIO needs proper settings
2) DT node for the RTC needs "wakeup-source" property
Kevin
^ permalink raw reply
* Re: [patch] mm, memcg: provide an anon_reclaimable stat
From: David Rientjes @ 2020-07-16 21:28 UTC (permalink / raw)
To: Shakeel Butt
Cc: SeongJae Park, Andrew Morton, Yang Shi, Michal Hocko, Yang Shi,
Roman Gushchin, Greg Thelen, Johannes Weiner, Vladimir Davydov,
Cgroups, Linux MM
In-Reply-To: <CALvZod6DbAUA-M9VXJW4RumeUD8qGf+BHM+9TUNeAr92JVkxsA@mail.gmail.com>
On Thu, 16 Jul 2020, Shakeel Butt wrote:
> > Userspace can lack insight into the amount of memory that can be reclaimed
> > from a memcg based on values from memory.stat. Two specific examples:
> >
> > - Lazy freeable memory (MADV_FREE) that are clean anonymous pages on the
> > inactive file LRU that can be quickly reclaimed under memory pressure
> > but otherwise shows up as mapped anon in memory.stat, and
> >
> > - Memory on deferred split queues (thp) that are compound pages that can
> > be split and uncharged from the memcg under memory pressure, but
> > otherwise shows up as charged anon LRU memory in memory.stat.
> >
> > Both of this anonymous usage is also charged to memory.current.
> >
> > Userspace can currently derive this information but it depends on kernel
> > implementation details for how this memory is handled for the purposes of
> > reclaim (anon on inactive file LRU or unmapped anon on the LRU).
> >
> > For the purposes of writing portable userspace code that does not need to
> > have insight into the kernel implementation for reclaimable memory, this
> > exports a stat that reveals the amount of anonymous memory that can be
> > reclaimed and uncharged from the memcg to start new applications.
> >
> > As the kernel implementation evolves for memory that can be reclaimed
> > under memory pressure, this stat can be kept consistent.
> >
> > Signed-off-by: David Rientjes <rientjes@google.com>
> > ---
> > Documentation/admin-guide/cgroup-v2.rst | 6 +++++
> > mm/memcontrol.c | 31 +++++++++++++++++++++++++
> > 2 files changed, 37 insertions(+)
> >
> > diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
> > --- a/Documentation/admin-guide/cgroup-v2.rst
> > +++ b/Documentation/admin-guide/cgroup-v2.rst
> > @@ -1296,6 +1296,12 @@ PAGE_SIZE multiple when read back.
> > Amount of memory used in anonymous mappings backed by
> > transparent hugepages
> >
> > + anon_reclaimable
> > + The amount of charged anonymous memory that can be reclaimed
> > + under memory pressure without swap. This currently includes
> > + lazy freeable memory (MADV_FREE) and compound pages that can be
> > + split and uncharged.
> > +
> > inactive_anon, active_anon, inactive_file, active_file, unevictable
> > Amount of memory, swap-backed and filesystem-backed,
> > on the internal memory management lists used by the
> > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -1350,6 +1350,32 @@ static bool mem_cgroup_wait_acct_move(struct mem_cgroup *memcg)
> > return false;
> > }
> >
> > +/*
> > + * Returns the amount of anon memory that is charged to the memcg that is
> > + * reclaimable under memory pressure without swap, in pages.
> > + */
> > +static unsigned long memcg_anon_reclaimable(struct mem_cgroup *memcg)
> > +{
> > + long deferred, lazyfree;
> > +
> > + /*
> > + * Deferred pages are charged anonymous pages that are on the LRU but
> > + * are unmapped. These compound pages are split under memory pressure.
> > + */
> > + deferred = max_t(long, memcg_page_state(memcg, NR_ACTIVE_ANON) +
> > + memcg_page_state(memcg, NR_INACTIVE_ANON) -
> > + memcg_page_state(memcg, NR_ANON_MAPPED), 0);
>
> Please note that the NR_ANON_MAPPED does not include tmpfs memory but
> NR_[IN]ACTIVE_ANON does include the tmpfs.
>
> > + /*
> > + * Lazyfree pages are charged clean anonymous pages that are on the file
> > + * LRU and can be reclaimed under memory pressure.
> > + */
> > + lazyfree = max_t(long, memcg_page_state(memcg, NR_ACTIVE_FILE) +
> > + memcg_page_state(memcg, NR_INACTIVE_FILE) -
> > + memcg_page_state(memcg, NR_FILE_PAGES), 0);
>
> Similarly NR_FILE_PAGES includes tmpfs memory but NR_[IN]ACTIVE_FILE does not.
>
Ah, so this adds to the motivation of providing the anon_reclaimable stat
because the calculation becomes even more convoluted and completely based
on the kernel implementation details for both lazyfree memory and deferred
split queues. Did you have a calculation in mind for
memcg_anon_reclaimable()?
^ permalink raw reply
* Re: [patch] mm, memcg: provide an anon_reclaimable stat
From: David Rientjes @ 2020-07-16 21:28 UTC (permalink / raw)
To: Shakeel Butt
Cc: SeongJae Park, Andrew Morton, Yang Shi, Michal Hocko, Yang Shi,
Roman Gushchin, Greg Thelen, Johannes Weiner, Vladimir Davydov,
Cgroups, Linux MM
In-Reply-To: <CALvZod6DbAUA-M9VXJW4RumeUD8qGf+BHM+9TUNeAr92JVkxsA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thu, 16 Jul 2020, Shakeel Butt wrote:
> > Userspace can lack insight into the amount of memory that can be reclaimed
> > from a memcg based on values from memory.stat. Two specific examples:
> >
> > - Lazy freeable memory (MADV_FREE) that are clean anonymous pages on the
> > inactive file LRU that can be quickly reclaimed under memory pressure
> > but otherwise shows up as mapped anon in memory.stat, and
> >
> > - Memory on deferred split queues (thp) that are compound pages that can
> > be split and uncharged from the memcg under memory pressure, but
> > otherwise shows up as charged anon LRU memory in memory.stat.
> >
> > Both of this anonymous usage is also charged to memory.current.
> >
> > Userspace can currently derive this information but it depends on kernel
> > implementation details for how this memory is handled for the purposes of
> > reclaim (anon on inactive file LRU or unmapped anon on the LRU).
> >
> > For the purposes of writing portable userspace code that does not need to
> > have insight into the kernel implementation for reclaimable memory, this
> > exports a stat that reveals the amount of anonymous memory that can be
> > reclaimed and uncharged from the memcg to start new applications.
> >
> > As the kernel implementation evolves for memory that can be reclaimed
> > under memory pressure, this stat can be kept consistent.
> >
> > Signed-off-by: David Rientjes <rientjes-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> > ---
> > Documentation/admin-guide/cgroup-v2.rst | 6 +++++
> > mm/memcontrol.c | 31 +++++++++++++++++++++++++
> > 2 files changed, 37 insertions(+)
> >
> > diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
> > --- a/Documentation/admin-guide/cgroup-v2.rst
> > +++ b/Documentation/admin-guide/cgroup-v2.rst
> > @@ -1296,6 +1296,12 @@ PAGE_SIZE multiple when read back.
> > Amount of memory used in anonymous mappings backed by
> > transparent hugepages
> >
> > + anon_reclaimable
> > + The amount of charged anonymous memory that can be reclaimed
> > + under memory pressure without swap. This currently includes
> > + lazy freeable memory (MADV_FREE) and compound pages that can be
> > + split and uncharged.
> > +
> > inactive_anon, active_anon, inactive_file, active_file, unevictable
> > Amount of memory, swap-backed and filesystem-backed,
> > on the internal memory management lists used by the
> > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -1350,6 +1350,32 @@ static bool mem_cgroup_wait_acct_move(struct mem_cgroup *memcg)
> > return false;
> > }
> >
> > +/*
> > + * Returns the amount of anon memory that is charged to the memcg that is
> > + * reclaimable under memory pressure without swap, in pages.
> > + */
> > +static unsigned long memcg_anon_reclaimable(struct mem_cgroup *memcg)
> > +{
> > + long deferred, lazyfree;
> > +
> > + /*
> > + * Deferred pages are charged anonymous pages that are on the LRU but
> > + * are unmapped. These compound pages are split under memory pressure.
> > + */
> > + deferred = max_t(long, memcg_page_state(memcg, NR_ACTIVE_ANON) +
> > + memcg_page_state(memcg, NR_INACTIVE_ANON) -
> > + memcg_page_state(memcg, NR_ANON_MAPPED), 0);
>
> Please note that the NR_ANON_MAPPED does not include tmpfs memory but
> NR_[IN]ACTIVE_ANON does include the tmpfs.
>
> > + /*
> > + * Lazyfree pages are charged clean anonymous pages that are on the file
> > + * LRU and can be reclaimed under memory pressure.
> > + */
> > + lazyfree = max_t(long, memcg_page_state(memcg, NR_ACTIVE_FILE) +
> > + memcg_page_state(memcg, NR_INACTIVE_FILE) -
> > + memcg_page_state(memcg, NR_FILE_PAGES), 0);
>
> Similarly NR_FILE_PAGES includes tmpfs memory but NR_[IN]ACTIVE_FILE does not.
>
Ah, so this adds to the motivation of providing the anon_reclaimable stat
because the calculation becomes even more convoluted and completely based
on the kernel implementation details for both lazyfree memory and deferred
split queues. Did you have a calculation in mind for
memcg_anon_reclaimable()?
^ permalink raw reply
* Re: [patch V3 02/13] entry: Provide generic syscall exit function
From: Thomas Gleixner @ 2020-07-16 21:28 UTC (permalink / raw)
To: Kees Cook
Cc: LKML, x86, linux-arch, Will Deacon, Arnd Bergmann, Mark Rutland,
Keno Fischer, Paolo Bonzini, kvm
In-Reply-To: <202007161354.62030182F@keescook>
Kees Cook <keescook@chromium.org> writes:
> On Thu, Jul 16, 2020 at 08:22:10PM +0200, Thomas Gleixner wrote:
>
> This looks correct to me. Did you happen to run the seccomp selftests
> under this series?
Yes, I threw the relevant self tests on it.
^ permalink raw reply
* + mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy.patch added to -mm tree
From: Andrew Morton @ 2020-07-16 21:28 UTC (permalink / raw)
To: cl, guro, iamjoonsoo.kim, mm-commits, penberg, rientjes, shakeelb,
songmuchun, stable, vbabka
In-Reply-To: <20200703151445.b6a0cfee402c7c5c4651f1b1@linux-foundation.org>
The patch titled
Subject: mm: memcg/slab: fix memory leak at non-root kmem_cache destroy
has been added to the -mm tree. Its filename is
mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy.patch
This patch should soon appear at
http://ozlabs.org/~akpm/mmots/broken-out/mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy.patch
and later at
http://ozlabs.org/~akpm/mmotm/broken-out/mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: Muchun Song <songmuchun@bytedance.com>
Subject: mm: memcg/slab: fix memory leak at non-root kmem_cache destroy
If the kmem_cache refcount is greater than one, we should not mark the
root kmem_cache as dying. If we mark the root kmem_cache dying
incorrectly, the non-root kmem_cache can never be destroyed. It resulted
in memory leak when memcg was destroyed. We can use the following steps
to reproduce.
1) Use kmem_cache_create() to create a new kmem_cache named A.
2) Coincidentally, the kmem_cache A is an alias for kmem_cache B,
so the refcount of B is just increased.
3) Use kmem_cache_destroy() to destroy the kmem_cache A, just
decrease the B's refcount but mark the B as dying.
4) Create a new memory cgroup and alloc memory from the kmem_cache
B. It leads to create a non-root kmem_cache for allocating memory.
5) When destroy the memory cgroup created in the step 4), the
non-root kmem_cache can never be destroyed.
If we repeat steps 4) and 5), this will cause a lot of memory leak. So
only when refcount reach zero, we mark the root kmem_cache as dying.
Link: http://lkml.kernel.org/r/20200716165103.83462-1-songmuchun@bytedance.com
Fixes: 92ee383f6daa ("mm: fix race between kmem_cache destroy, create and deactivate")
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Acked-by: Roman Gushchin <guro@fb.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
mm/slab_common.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
--- a/mm/slab_common.c~mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy
+++ a/mm/slab_common.c
@@ -326,6 +326,14 @@ int slab_unmergeable(struct kmem_cache *
if (s->refcount < 0)
return 1;
+#ifdef CONFIG_MEMCG_KMEM
+ /*
+ * Skip the dying kmem_cache.
+ */
+ if (s->memcg_params.dying)
+ return 1;
+#endif
+
return 0;
}
@@ -886,12 +894,15 @@ static int shutdown_memcg_caches(struct
return 0;
}
-static void flush_memcg_workqueue(struct kmem_cache *s)
+static void memcg_set_kmem_cache_dying(struct kmem_cache *s)
{
spin_lock_irq(&memcg_kmem_wq_lock);
s->memcg_params.dying = true;
spin_unlock_irq(&memcg_kmem_wq_lock);
+}
+static void flush_memcg_workqueue(struct kmem_cache *s)
+{
/*
* SLAB and SLUB deactivate the kmem_caches through call_rcu. Make
* sure all registered rcu callbacks have been invoked.
@@ -923,10 +934,6 @@ static inline int shutdown_memcg_caches(
{
return 0;
}
-
-static inline void flush_memcg_workqueue(struct kmem_cache *s)
-{
-}
#endif /* CONFIG_MEMCG_KMEM */
void slab_kmem_cache_release(struct kmem_cache *s)
@@ -944,8 +951,6 @@ void kmem_cache_destroy(struct kmem_cach
if (unlikely(!s))
return;
- flush_memcg_workqueue(s);
-
get_online_cpus();
get_online_mems();
@@ -955,6 +960,22 @@ void kmem_cache_destroy(struct kmem_cach
if (s->refcount)
goto out_unlock;
+#ifdef CONFIG_MEMCG_KMEM
+ memcg_set_kmem_cache_dying(s);
+
+ mutex_unlock(&slab_mutex);
+
+ put_online_mems();
+ put_online_cpus();
+
+ flush_memcg_workqueue(s);
+
+ get_online_cpus();
+ get_online_mems();
+
+ mutex_lock(&slab_mutex);
+#endif
+
err = shutdown_memcg_caches(s);
if (!err)
err = shutdown_cache(s);
_
Patches currently in -mm which might be from songmuchun@bytedance.com are
mm-memcg-slab-fix-memory-leak-at-non-root-kmem_cache-destroy.patch
mm-page_alloc-skip-setting-nodemask-when-we-are-in-interrupt.patch
^ permalink raw reply
* [Buildroot] [PATCH v3 1/1] package/rpi-firmware: bad startup file names
From: Peter Seiderer @ 2020-07-16 21:28 UTC (permalink / raw)
To: buildroot
In-Reply-To: <87sgdrs9r2.fsf@dell.be.48ers.dk>
Hello Peter,
On Thu, 16 Jul 2020 18:30:25 +0200, Peter Korsgaard <peter@korsgaard.com> wrote:
> >>>>> "St?phane" == St?phane Veyret <sveyret@gmail.com> writes:
>
> > When booting, a Raspberry Pi will load the appropriate start files,
> > depending on the provided configuration. For example, if the config.txt
> > file contains ?gpu_mem=16? the board will automatically load the
> > cut-down startup files (start_cd.elf and fixup_cd.dat on non-Rpi4).
>
> > Unfortunately, even when the appropriate version is selected in the
> > configuration menu, if the rpi-firmware makefile takes the good files,
> > it renames them to non-qualified, i.e. start.elf and fixup.dat. But as
> > these are not the files searched by the Raspberry Pi, the board will not
> > start.
>
> > This patch will set the names of the files to load as constant in the
> > config.txt file. This guarantees that the rpi firmware blobs do not take
> > any other corner-case decision based on any other as-yet unknown
> > conditions.
>
> > This eases the maintenance, as only the names of the source files
> > matter; the destination filenames are constants, and so are the
> > filenames in config.txt.
>
> > Fixes: #13026
>
> > Signed-off-by: St?phane Veyret <sveyret@gmail.com>
>
> > ---
> > Changes v2 -> v3:
> > - factorization of start file copy, rework on code (suggested by
> > Yann E. MORIN).
> > Changes v1 -> v2:
> > - update config.txt instead of keeping firmware name (suggested by
> > Yann E. MORIN).
>
> Committed to 2020.02.x and 2020.05.x, thanks.
>
This one needs [1] too...
Regards,
Peter
[1] https://git.buildroot.net/buildroot/commit/?id=59c3426c5197fc2df1c8307543ed54edbb22f595
^ permalink raw reply
* Re: [PATCH v3 2/4] clocksource/drivers: Add CLINT timer driver
From: Daniel Lezcano @ 2020-07-16 21:27 UTC (permalink / raw)
To: Anup Patel, Palmer Dabbelt, Paul Walmsley, Albert Ou, Rob Herring,
Thomas Gleixner
Cc: devicetree, Damien Le Moal, Anup Patel, linux-kernel, Atish Patra,
Alistair Francis, linux-riscv
In-Reply-To: <20200715071506.10994-3-anup.patel@wdc.com>
Hi Anup,
On 15/07/2020 09:15, Anup Patel wrote:
> The TIME CSR and SBI calls are not available in RISC-V M-mode so we
> separate add CLINT driver for Linux RISC-V M-mode (i.e. RISC-V NoMMU
> kernel).
The description is confusing, please reword it and give a bit more
information about the timer itself, especially, the IPI thing.
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> ---
> drivers/clocksource/Kconfig | 10 ++
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/timer-clint.c | 229 ++++++++++++++++++++++++++++++
> include/linux/cpuhotplug.h | 1 +
> 4 files changed, 241 insertions(+)
> create mode 100644 drivers/clocksource/timer-clint.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 91418381fcd4..eabcf1cfb0c0 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -658,6 +658,16 @@ config RISCV_TIMER
> is accessed via both the SBI and the rdcycle instruction. This is
> required for all RISC-V systems.
>
> +config CLINT_TIMER
> + bool "Timer for the RISC-V platform"
> + depends on GENERIC_SCHED_CLOCK && RISCV_M_MODE
> + default y
> + select TIMER_PROBE
> + select TIMER_OF
> + help
> + This option enables the CLINT timer for RISC-V systems. The CLINT
> + driver is usually used for NoMMU RISC-V systems.
For the timer, we do silent option and let the platform config select
it. Please refer to other timer option below as reference.
> config CSKY_MP_TIMER
> bool "SMP Timer for the C-SKY platform" if COMPILE_TEST
> depends on CSKY
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index bdda1a2e4097..18e700e703a0 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -87,6 +87,7 @@ obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
> obj-$(CONFIG_X86_NUMACHIP) += numachip.o
> obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
> obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
> +obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
> obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
> obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
> diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
> new file mode 100644
> index 000000000000..bfc38bb5a589
> --- /dev/null
> +++ b/drivers/clocksource/timer-clint.c
> @@ -0,0 +1,229 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + *
> + * Most of the M-mode (i.e. NoMMU) RISC-V systems usually have a
> + * CLINT MMIO timer device.
> + */
> +
> +#define pr_fmt(fmt) "clint: " fmt
> +#include <linux/bitops.h>
> +#include <linux/clocksource.h>
> +#include <linux/clockchips.h>
> +#include <linux/cpu.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/sched_clock.h>
> +#include <linux/io-64-nonatomic-lo-hi.h>
> +#include <linux/interrupt.h>
> +#include <linux/of_irq.h>
> +#include <linux/smp.h>
> +
> +#define CLINT_IPI_OFF 0
> +#define CLINT_TIMER_CMP_OFF 0x4000
> +#define CLINT_TIMER_VAL_OFF 0xbff8
> +
> +/* CLINT manages IPI and Timer for RISC-V M-mode */
> +static u32 __iomem *clint_ipi_base;
> +static u64 __iomem *clint_timer_cmp;
> +static u64 __iomem *clint_timer_val;
> +static unsigned long clint_timer_freq;
> +static unsigned int clint_timer_irq;
> +
> +static void clint_send_ipi(const struct cpumask *target)
> +{
> + unsigned int cpu;
> +
> + for_each_cpu(cpu, target)
> + writel(1, clint_ipi_base + cpuid_to_hartid_map(cpu));
> +}
> +
> +static void clint_clear_ipi(void)
> +{
> + writel(0, clint_ipi_base + cpuid_to_hartid_map(smp_processor_id()));
> +}
> +
> +static struct riscv_ipi_ops clint_ipi_ops = {
> + .ipi_inject = clint_send_ipi,
> + .ipi_clear = clint_clear_ipi,
> +};
> +
> +#ifdef CONFIG_64BIT
> +#define clint_get_cycles() readq_relaxed(clint_timer_val)
> +#else
> +#define clint_get_cycles() readl_relaxed(clint_timer_val)
> +#define clint_get_cycles_hi() readl_relaxed(((u32 *)clint_timer_val) + 1)
> +#endif
> +
> +#ifdef CONFIG_64BIT
> +static u64 clint_get_cycles64(void)
> +{
> + return clint_get_cycles();
> +}
> +#else /* CONFIG_64BIT */
> +static u64 clint_get_cycles64(void)
> +{
> + u32 hi, lo;
> +
> + do {
> + hi = clint_get_cycles_hi();
> + lo = clint_get_cycles();
> + } while (hi != clint_get_cycles_hi());
> +
> + return ((u64)hi << 32) | lo;
> +}
> +#endif /* CONFIG_64BIT */
> +static int clint_clock_next_event(unsigned long delta,
> + struct clock_event_device *ce)
> +{
> + void __iomem *r = clint_timer_cmp +
> + cpuid_to_hartid_map(smp_processor_id());
> +
> + csr_set(CSR_IE, IE_TIE);
> + writeq_relaxed(clint_get_cycles64() + delta, r);
> + return 0;
> +}
> +
> +static DEFINE_PER_CPU(struct clock_event_device, clint_clock_event) = {
> + .name = "clint_clockevent",
> + .features = CLOCK_EVT_FEAT_ONESHOT,
> + .rating = 100,
> + .set_next_event = clint_clock_next_event,
> +};
> +
> +static u64 clint_rdtime(struct clocksource *cs)
> +{
> + return readq_relaxed(clint_timer_val);
> +}
> +
> +static u64 notrace clint_sched_clock(void)
> +{
> + return readq_relaxed(clint_timer_val);
> +}
> +
> +static struct clocksource clint_clocksource = {
> + .name = "clint_clocksource",
> + .rating = 300,
> + .mask = CLOCKSOURCE_MASK(64),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> + .read = clint_rdtime,
What if !CONFIG_64BIT
> +};
> +
> +static int clint_timer_starting_cpu(unsigned int cpu)
> +{
> + struct clock_event_device *ce = per_cpu_ptr(&clint_clock_event, cpu);
> +
> + ce->cpumask = cpumask_of(cpu);
> + clockevents_config_and_register(ce, clint_timer_freq, 200, ULONG_MAX);
The function is not immune against registering the same clockevents. If
the CPU is hotplugged several times, this function will be called again
and again. Why not rely on a for_each_possible_cpu loop in the init
function ?
> + enable_percpu_irq(clint_timer_irq,
> + irq_get_trigger_type(clint_timer_irq));
Why do you want to enable / disable the interrrupts ? The should be
already handle by the hotplug framework no ?
> + return 0;
> +}
> +
> +static int clint_timer_dying_cpu(unsigned int cpu)
> +{
> + disable_percpu_irq(clint_timer_irq);
> + return 0;
> +}
> +
> +static irqreturn_t clint_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evdev = this_cpu_ptr(&clint_clock_event);
> +
> + csr_clear(CSR_IE, IE_TIE);
> + evdev->event_handler(evdev);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int __init clint_timer_init_dt(struct device_node *np)
> +{
> + int rc;
> + u32 i, nr_irqs;
> + void __iomem *base;
> + struct of_phandle_args oirq;
> +
> + /*
> + * Ensure that CLINT device interrupts are either RV_IRQ_TIMER or
> + * RV_IRQ_SOFT. If it's anything else then we ignore the device.
> + */
> + nr_irqs = of_irq_count(np);
> + for (i = 0; i < nr_irqs; i++) {
> + if (of_irq_parse_one(np, i, &oirq)) {
> + pr_err("%pOFP: failed to parse irq %d.\n", np, i);
> + continue;
> + }
> +
> + if ((oirq.args_count != 1) ||
> + (oirq.args[0] != RV_IRQ_TIMER &&
> + oirq.args[0] != RV_IRQ_SOFT)) {
> + pr_err("%pOFP: invalid irq %d (hwirq %d)\n",
> + np, i, oirq.args[0]);
> + return -ENODEV;
> + }
> +
> + /* Find parent irq domain and map timer irq */
> + if (!clint_timer_irq &&
> + oirq.args[0] == RV_IRQ_TIMER &&
> + irq_find_host(oirq.np))
> + clint_timer_irq = irq_of_parse_and_map(np, i);
> + }
> +
> + /* If CLINT timer irq not found then fail */
> + if (!clint_timer_irq) {
> + pr_err("%pOFP: timer irq not found\n", np);
> + return -ENODEV;
> + }
> +
> + base = of_iomap(np, 0);
> + if (!base) {
> + pr_err("%pOFP: could not map registers\n", np);
> + return -ENODEV;
> + }
> +
> + clint_ipi_base = base + CLINT_IPI_OFF;
> + clint_timer_cmp = base + CLINT_TIMER_CMP_OFF;
> + clint_timer_val = base + CLINT_TIMER_VAL_OFF;
> + clint_timer_freq = riscv_timebase;
> +
> + pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
> +
> + rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
> + if (rc) {
> + iounmap(base);
> + pr_err("%pOFP: clocksource register failed [%d]\n", np, rc);
> + return rc;
> + }
> +
> + sched_clock_register(clint_sched_clock, 64, clint_timer_freq);
> +
> + rc = request_percpu_irq(clint_timer_irq, clint_timer_interrupt,
> + "clint-timer", &clint_clock_event);
> + if (rc) {
> + iounmap(base);
> + pr_err("registering percpu irq failed [%d]\n", rc);
> + return rc;
> + }
> +
> + rc = cpuhp_setup_state(CPUHP_AP_CLINT_TIMER_STARTING,
> + "clockevents/clint/timer:starting",
> + clint_timer_starting_cpu,
> + clint_timer_dying_cpu);
> + if (rc) {
> + free_irq(clint_timer_irq, &clint_clock_event);
> + iounmap(base);
> + pr_err("%pOFP: cpuhp setup state failed [%d]\n", np, rc);
> + return rc;
> + }
> +
> + riscv_set_ipi_ops(&clint_ipi_ops);
> + clint_clear_ipi();
> +
> + return 0;
> +}
> +
> +TIMER_OF_DECLARE(clint_timer, "riscv,clint0", clint_timer_init_dt);
> +TIMER_OF_DECLARE(clint_timer1, "sifive,clint0", clint_timer_init_dt);
> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 191772d4a4d7..1451f4625833 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -132,6 +132,7 @@ enum cpuhp_state {
> CPUHP_AP_MIPS_GIC_TIMER_STARTING,
> CPUHP_AP_ARC_TIMER_STARTING,
> CPUHP_AP_RISCV_TIMER_STARTING,
> + CPUHP_AP_CLINT_TIMER_STARTING,
> CPUHP_AP_CSKY_TIMER_STARTING,
> CPUHP_AP_HYPERV_TIMER_STARTING,
> CPUHP_AP_KVM_STARTING,
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply
* Re: [PATCH v3 2/4] clocksource/drivers: Add CLINT timer driver
From: Daniel Lezcano @ 2020-07-16 21:27 UTC (permalink / raw)
To: Anup Patel, Palmer Dabbelt, Paul Walmsley, Albert Ou, Rob Herring,
Thomas Gleixner
Cc: Damien Le Moal, Atish Patra, Alistair Francis, Anup Patel,
linux-riscv, linux-kernel, devicetree
In-Reply-To: <20200715071506.10994-3-anup.patel@wdc.com>
Hi Anup,
On 15/07/2020 09:15, Anup Patel wrote:
> The TIME CSR and SBI calls are not available in RISC-V M-mode so we
> separate add CLINT driver for Linux RISC-V M-mode (i.e. RISC-V NoMMU
> kernel).
The description is confusing, please reword it and give a bit more
information about the timer itself, especially, the IPI thing.
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> ---
> drivers/clocksource/Kconfig | 10 ++
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/timer-clint.c | 229 ++++++++++++++++++++++++++++++
> include/linux/cpuhotplug.h | 1 +
> 4 files changed, 241 insertions(+)
> create mode 100644 drivers/clocksource/timer-clint.c
>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 91418381fcd4..eabcf1cfb0c0 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -658,6 +658,16 @@ config RISCV_TIMER
> is accessed via both the SBI and the rdcycle instruction. This is
> required for all RISC-V systems.
>
> +config CLINT_TIMER
> + bool "Timer for the RISC-V platform"
> + depends on GENERIC_SCHED_CLOCK && RISCV_M_MODE
> + default y
> + select TIMER_PROBE
> + select TIMER_OF
> + help
> + This option enables the CLINT timer for RISC-V systems. The CLINT
> + driver is usually used for NoMMU RISC-V systems.
For the timer, we do silent option and let the platform config select
it. Please refer to other timer option below as reference.
> config CSKY_MP_TIMER
> bool "SMP Timer for the C-SKY platform" if COMPILE_TEST
> depends on CSKY
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index bdda1a2e4097..18e700e703a0 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -87,6 +87,7 @@ obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
> obj-$(CONFIG_X86_NUMACHIP) += numachip.o
> obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
> obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
> +obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
> obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
> obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
> diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
> new file mode 100644
> index 000000000000..bfc38bb5a589
> --- /dev/null
> +++ b/drivers/clocksource/timer-clint.c
> @@ -0,0 +1,229 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + *
> + * Most of the M-mode (i.e. NoMMU) RISC-V systems usually have a
> + * CLINT MMIO timer device.
> + */
> +
> +#define pr_fmt(fmt) "clint: " fmt
> +#include <linux/bitops.h>
> +#include <linux/clocksource.h>
> +#include <linux/clockchips.h>
> +#include <linux/cpu.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/sched_clock.h>
> +#include <linux/io-64-nonatomic-lo-hi.h>
> +#include <linux/interrupt.h>
> +#include <linux/of_irq.h>
> +#include <linux/smp.h>
> +
> +#define CLINT_IPI_OFF 0
> +#define CLINT_TIMER_CMP_OFF 0x4000
> +#define CLINT_TIMER_VAL_OFF 0xbff8
> +
> +/* CLINT manages IPI and Timer for RISC-V M-mode */
> +static u32 __iomem *clint_ipi_base;
> +static u64 __iomem *clint_timer_cmp;
> +static u64 __iomem *clint_timer_val;
> +static unsigned long clint_timer_freq;
> +static unsigned int clint_timer_irq;
> +
> +static void clint_send_ipi(const struct cpumask *target)
> +{
> + unsigned int cpu;
> +
> + for_each_cpu(cpu, target)
> + writel(1, clint_ipi_base + cpuid_to_hartid_map(cpu));
> +}
> +
> +static void clint_clear_ipi(void)
> +{
> + writel(0, clint_ipi_base + cpuid_to_hartid_map(smp_processor_id()));
> +}
> +
> +static struct riscv_ipi_ops clint_ipi_ops = {
> + .ipi_inject = clint_send_ipi,
> + .ipi_clear = clint_clear_ipi,
> +};
> +
> +#ifdef CONFIG_64BIT
> +#define clint_get_cycles() readq_relaxed(clint_timer_val)
> +#else
> +#define clint_get_cycles() readl_relaxed(clint_timer_val)
> +#define clint_get_cycles_hi() readl_relaxed(((u32 *)clint_timer_val) + 1)
> +#endif
> +
> +#ifdef CONFIG_64BIT
> +static u64 clint_get_cycles64(void)
> +{
> + return clint_get_cycles();
> +}
> +#else /* CONFIG_64BIT */
> +static u64 clint_get_cycles64(void)
> +{
> + u32 hi, lo;
> +
> + do {
> + hi = clint_get_cycles_hi();
> + lo = clint_get_cycles();
> + } while (hi != clint_get_cycles_hi());
> +
> + return ((u64)hi << 32) | lo;
> +}
> +#endif /* CONFIG_64BIT */
> +static int clint_clock_next_event(unsigned long delta,
> + struct clock_event_device *ce)
> +{
> + void __iomem *r = clint_timer_cmp +
> + cpuid_to_hartid_map(smp_processor_id());
> +
> + csr_set(CSR_IE, IE_TIE);
> + writeq_relaxed(clint_get_cycles64() + delta, r);
> + return 0;
> +}
> +
> +static DEFINE_PER_CPU(struct clock_event_device, clint_clock_event) = {
> + .name = "clint_clockevent",
> + .features = CLOCK_EVT_FEAT_ONESHOT,
> + .rating = 100,
> + .set_next_event = clint_clock_next_event,
> +};
> +
> +static u64 clint_rdtime(struct clocksource *cs)
> +{
> + return readq_relaxed(clint_timer_val);
> +}
> +
> +static u64 notrace clint_sched_clock(void)
> +{
> + return readq_relaxed(clint_timer_val);
> +}
> +
> +static struct clocksource clint_clocksource = {
> + .name = "clint_clocksource",
> + .rating = 300,
> + .mask = CLOCKSOURCE_MASK(64),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> + .read = clint_rdtime,
What if !CONFIG_64BIT
> +};
> +
> +static int clint_timer_starting_cpu(unsigned int cpu)
> +{
> + struct clock_event_device *ce = per_cpu_ptr(&clint_clock_event, cpu);
> +
> + ce->cpumask = cpumask_of(cpu);
> + clockevents_config_and_register(ce, clint_timer_freq, 200, ULONG_MAX);
The function is not immune against registering the same clockevents. If
the CPU is hotplugged several times, this function will be called again
and again. Why not rely on a for_each_possible_cpu loop in the init
function ?
> + enable_percpu_irq(clint_timer_irq,
> + irq_get_trigger_type(clint_timer_irq));
Why do you want to enable / disable the interrrupts ? The should be
already handle by the hotplug framework no ?
> + return 0;
> +}
> +
> +static int clint_timer_dying_cpu(unsigned int cpu)
> +{
> + disable_percpu_irq(clint_timer_irq);
> + return 0;
> +}
> +
> +static irqreturn_t clint_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evdev = this_cpu_ptr(&clint_clock_event);
> +
> + csr_clear(CSR_IE, IE_TIE);
> + evdev->event_handler(evdev);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int __init clint_timer_init_dt(struct device_node *np)
> +{
> + int rc;
> + u32 i, nr_irqs;
> + void __iomem *base;
> + struct of_phandle_args oirq;
> +
> + /*
> + * Ensure that CLINT device interrupts are either RV_IRQ_TIMER or
> + * RV_IRQ_SOFT. If it's anything else then we ignore the device.
> + */
> + nr_irqs = of_irq_count(np);
> + for (i = 0; i < nr_irqs; i++) {
> + if (of_irq_parse_one(np, i, &oirq)) {
> + pr_err("%pOFP: failed to parse irq %d.\n", np, i);
> + continue;
> + }
> +
> + if ((oirq.args_count != 1) ||
> + (oirq.args[0] != RV_IRQ_TIMER &&
> + oirq.args[0] != RV_IRQ_SOFT)) {
> + pr_err("%pOFP: invalid irq %d (hwirq %d)\n",
> + np, i, oirq.args[0]);
> + return -ENODEV;
> + }
> +
> + /* Find parent irq domain and map timer irq */
> + if (!clint_timer_irq &&
> + oirq.args[0] == RV_IRQ_TIMER &&
> + irq_find_host(oirq.np))
> + clint_timer_irq = irq_of_parse_and_map(np, i);
> + }
> +
> + /* If CLINT timer irq not found then fail */
> + if (!clint_timer_irq) {
> + pr_err("%pOFP: timer irq not found\n", np);
> + return -ENODEV;
> + }
> +
> + base = of_iomap(np, 0);
> + if (!base) {
> + pr_err("%pOFP: could not map registers\n", np);
> + return -ENODEV;
> + }
> +
> + clint_ipi_base = base + CLINT_IPI_OFF;
> + clint_timer_cmp = base + CLINT_TIMER_CMP_OFF;
> + clint_timer_val = base + CLINT_TIMER_VAL_OFF;
> + clint_timer_freq = riscv_timebase;
> +
> + pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
> +
> + rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
> + if (rc) {
> + iounmap(base);
> + pr_err("%pOFP: clocksource register failed [%d]\n", np, rc);
> + return rc;
> + }
> +
> + sched_clock_register(clint_sched_clock, 64, clint_timer_freq);
> +
> + rc = request_percpu_irq(clint_timer_irq, clint_timer_interrupt,
> + "clint-timer", &clint_clock_event);
> + if (rc) {
> + iounmap(base);
> + pr_err("registering percpu irq failed [%d]\n", rc);
> + return rc;
> + }
> +
> + rc = cpuhp_setup_state(CPUHP_AP_CLINT_TIMER_STARTING,
> + "clockevents/clint/timer:starting",
> + clint_timer_starting_cpu,
> + clint_timer_dying_cpu);
> + if (rc) {
> + free_irq(clint_timer_irq, &clint_clock_event);
> + iounmap(base);
> + pr_err("%pOFP: cpuhp setup state failed [%d]\n", np, rc);
> + return rc;
> + }
> +
> + riscv_set_ipi_ops(&clint_ipi_ops);
> + clint_clear_ipi();
> +
> + return 0;
> +}
> +
> +TIMER_OF_DECLARE(clint_timer, "riscv,clint0", clint_timer_init_dt);
> +TIMER_OF_DECLARE(clint_timer1, "sifive,clint0", clint_timer_init_dt);
> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 191772d4a4d7..1451f4625833 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -132,6 +132,7 @@ enum cpuhp_state {
> CPUHP_AP_MIPS_GIC_TIMER_STARTING,
> CPUHP_AP_ARC_TIMER_STARTING,
> CPUHP_AP_RISCV_TIMER_STARTING,
> + CPUHP_AP_CLINT_TIMER_STARTING,
> CPUHP_AP_CSKY_TIMER_STARTING,
> CPUHP_AP_HYPERV_TIMER_STARTING,
> CPUHP_AP_KVM_STARTING,
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: pinctrl: Add bindings for Actions S500 SoC
From: Cristian Ciocaltea @ 2020-07-16 21:26 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree, Linus Walleij, linux-actions,
linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM,
Manivannan Sadhasivam, Andreas Färber,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CAL_Jsq+8bX5duv=116e=hve1L-h8a=5quqCHVtSAs4PjK6xc1w@mail.gmail.com>
On Thu, Jul 16, 2020 at 08:50:36AM -0600, Rob Herring wrote:
> On Thu, Jul 16, 2020 at 4:43 AM Cristian Ciocaltea
> <cristian.ciocaltea@gmail.com> wrote:
> >
> > On Wed, Jul 15, 2020 at 02:03:09PM -0600, Rob Herring wrote:
> > > On Thu, Jun 25, 2020 at 11:16:18PM +0300, Cristian Ciocaltea wrote:
> > > > Add pinctrl and gpio bindings for Actions Semi S500 SoC.
> > > >
> > > > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
> > > > ---
> > > > .../pinctrl/actions,s500-pinctrl.yaml | 228 ++++++++++++++++++
> > > > 1 file changed, 228 insertions(+)
> > > > create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > > new file mode 100644
> > > > index 000000000000..856947c70844
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > > @@ -0,0 +1,228 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/pinctrl/actions,s500-pinctrl.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Actions Semi S500 SoC pinmux & GPIO controller
> > > > +
> > > > +maintainers:
> > > > + - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > > > +
> > > > +description: |
> > > > + Pinmux & GPIO controller manages pin multiplexing & configuration including
> > > > + GPIO function selection & GPIO attributes configuration. Please refer to
> > > > + pinctrl-bindings.txt in this directory for common binding part and usage.
> > > > +
> > > > +properties:
> > > > + compatible:
> > > > + const: actions,s500-pinctrl
> > > > +
> > > > + reg:
> > > > + minItems: 1
> > > > + maxItems: 4
> > >
> > > Need to enumerate what each register range is.
> >
> > Hi Rob,
> >
> > Thanks for the review!
> >
> > Would the update below suffice?
> >
> > reg:
> > description: |
> > Specifies the memory region(s) associated with the pin-controller.
> > To improve granularity, up to four register ranges can be provided:
>
> What does 'improve granularity' mean:
Technically all the registers used by the driver could be specified via
a single contiguous range. However, there are a few unrelated registers
(i.e. PWM Output Control) which should be excluded in order to come up
with a more accurate specification. The 4 ranges below are basically
the result of this exclusion:
> > * GPIO Output + GPIO Input + GPIO Data
> > * Multiplexing Control
> > * PAD Pull Control + PAD Schmitt Trigger enable + PAD Control
> > * PAD Drive Capacity Select
>
> The h/w sometimes has these and sometimes doesn't?
No, the h/w is fixed, the only reason of this approach was to allow a
precise memory region specification, as explained above.
I'm not sure if this should be made mandatory or it's also fine to let
(a lazy) user provide combined ranges or just a contiguous one (like
in the example), with the drawback of loosing the accuracy, of course.
> If they do stay, then you want:
>
> items:
> - description: GPIO Output + GPIO Input + GPIO Data
> - description: ...
Would this be applicable even if we keep this flexible approach and
don't set 'minItems: 4'?
> >
> > > > +
> > > > + clocks:
> > > > + maxItems: 1
> > > > +
> > > > + gpio-controller: true
> > > > +
> > > > + gpio-ranges:
> > > > + maxItems: 1
> > > > +
> > > > + '#gpio-cells':
> > > > + description:
> > > > + Specifies the pin number and flags, as defined in
> > > > + include/dt-bindings/gpio/gpio.h
> > > > + const: 2
> > > > +
> > > > + interrupt-controller: true
> > > > +
> > > > + '#interrupt-cells':
> > > > + description:
> > > > + Specifies the pin number and flags, as defined in
> > > > + include/dt-bindings/interrupt-controller/irq.h
> > > > + const: 2
> > > > +
> > > > + interrupts:
> > > > + description:
> > > > + One interrupt per each of the 5 GPIO ports supported by the controller,
> > > > + sorted by port number ascending order.
> > > > + minItems: 5
> > > > + maxItems: 5
> > > > +
> > > > +patternProperties:
> > > > + '^.*$':
> > > > + if:
> > > > + type: object
> > >
> > > For a new binding, can you do '-pins$' for the node names so we don't
> > > need this if/then hack.
> >
> > Right, the idea was to be consistent with the existing bindings for
> > S700 and S900, which allow free node names, although they are not yet
> > converted to yaml format.
>
> If we want consistency, those should have their node names updated.
Fair enough, I have already updated the node names to use the '-pins'
suffix.
> >
> > > > + then:
> > > > + patternProperties:
> > > > + 'pinmux$':
> > >
> > > Is this really a pattern? Can't tell from the example.
> >
> > pinmux and pinconf subnodes may appear multiple times, that's why I
> > decided to match their names based on the suffix.
> >
> > The example is not complex enough, I will change it to the following:
> >
> > mmc0_default: mmc0_default {
> > pinmux {
> > groups = "sd0_d0_mfp", "sd0_d1_mfp", "sd0_d2_d3_mfp",
> > "sd0_cmd_mfp", "sd0_clk_mfp";
> > function = "sd0";
> > };
> >
> > drv_pinconf {
>
> drv-pinconf
>
> Make the pattern '-?pinconf' to enforce that. (that '-' may need escaping?)
Actually the pattern should be '^(.*-)?pinconf$', to restrict the names
to either 'pinconf' or '<label>-pinconf'.
I have just made some more validation tests and noticed I had missed an
'additionalProperties: false' line, for the 'pins' node. Should be fine
now!
Thanks,
Cristi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH RFC v2 2/3] io_uring: add IOURING_REGISTER_RESTRICTIONS opcode
From: Jens Axboe @ 2020-07-16 21:26 UTC (permalink / raw)
To: Stefano Garzarella
Cc: Alexander Viro, Kernel Hardening, Kees Cook, Aleksa Sarai,
Stefan Hajnoczi, Christian Brauner, Sargun Dhillon, Jann Horn,
io-uring, linux-fsdevel, Jeff Moyer, linux-kernel
In-Reply-To: <20200716124833.93667-3-sgarzare@redhat.com>
On 7/16/20 6:48 AM, Stefano Garzarella wrote:
> diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
> index efc50bd0af34..0774d5382c65 100644
> --- a/include/uapi/linux/io_uring.h
> +++ b/include/uapi/linux/io_uring.h
> @@ -265,6 +265,7 @@ enum {
> IORING_REGISTER_PROBE,
> IORING_REGISTER_PERSONALITY,
> IORING_UNREGISTER_PERSONALITY,
> + IORING_REGISTER_RESTRICTIONS,
>
> /* this goes last */
> IORING_REGISTER_LAST
> @@ -293,4 +294,30 @@ struct io_uring_probe {
> struct io_uring_probe_op ops[0];
> };
>
> +struct io_uring_restriction {
> + __u16 opcode;
> + union {
> + __u8 register_op; /* IORING_RESTRICTION_REGISTER_OP */
> + __u8 sqe_op; /* IORING_RESTRICTION_SQE_OP */
> + };
> + __u8 resv;
> + __u32 resv2[3];
> +};
> +
> +/*
> + * io_uring_restriction->opcode values
> + */
> +enum {
> + /* Allow an io_uring_register(2) opcode */
> + IORING_RESTRICTION_REGISTER_OP,
> +
> + /* Allow an sqe opcode */
> + IORING_RESTRICTION_SQE_OP,
> +
> + /* Only allow fixed files */
> + IORING_RESTRICTION_FIXED_FILES_ONLY,
> +
> + IORING_RESTRICTION_LAST
> +};
> +
Not sure I totally love this API. Maybe it'd be cleaner to have separate
ops for this, instead of muxing it like this. One for registering op
code restrictions, and one for disallowing other parts (like fixed
files, etc).
I think that would look a lot cleaner than the above.
--
Jens Axboe
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: pinctrl: Add bindings for Actions S500 SoC
From: Cristian Ciocaltea @ 2020-07-16 21:26 UTC (permalink / raw)
To: Rob Herring
Cc: Andreas Färber, Manivannan Sadhasivam, Linus Walleij,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
open list:GPIO SUBSYSTEM, devicetree,
linux-kernel@vger.kernel.org, linux-actions
In-Reply-To: <CAL_Jsq+8bX5duv=116e=hve1L-h8a=5quqCHVtSAs4PjK6xc1w@mail.gmail.com>
On Thu, Jul 16, 2020 at 08:50:36AM -0600, Rob Herring wrote:
> On Thu, Jul 16, 2020 at 4:43 AM Cristian Ciocaltea
> <cristian.ciocaltea@gmail.com> wrote:
> >
> > On Wed, Jul 15, 2020 at 02:03:09PM -0600, Rob Herring wrote:
> > > On Thu, Jun 25, 2020 at 11:16:18PM +0300, Cristian Ciocaltea wrote:
> > > > Add pinctrl and gpio bindings for Actions Semi S500 SoC.
> > > >
> > > > Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
> > > > ---
> > > > .../pinctrl/actions,s500-pinctrl.yaml | 228 ++++++++++++++++++
> > > > 1 file changed, 228 insertions(+)
> > > > create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > > new file mode 100644
> > > > index 000000000000..856947c70844
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/pinctrl/actions,s500-pinctrl.yaml
> > > > @@ -0,0 +1,228 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/pinctrl/actions,s500-pinctrl.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Actions Semi S500 SoC pinmux & GPIO controller
> > > > +
> > > > +maintainers:
> > > > + - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > > > +
> > > > +description: |
> > > > + Pinmux & GPIO controller manages pin multiplexing & configuration including
> > > > + GPIO function selection & GPIO attributes configuration. Please refer to
> > > > + pinctrl-bindings.txt in this directory for common binding part and usage.
> > > > +
> > > > +properties:
> > > > + compatible:
> > > > + const: actions,s500-pinctrl
> > > > +
> > > > + reg:
> > > > + minItems: 1
> > > > + maxItems: 4
> > >
> > > Need to enumerate what each register range is.
> >
> > Hi Rob,
> >
> > Thanks for the review!
> >
> > Would the update below suffice?
> >
> > reg:
> > description: |
> > Specifies the memory region(s) associated with the pin-controller.
> > To improve granularity, up to four register ranges can be provided:
>
> What does 'improve granularity' mean:
Technically all the registers used by the driver could be specified via
a single contiguous range. However, there are a few unrelated registers
(i.e. PWM Output Control) which should be excluded in order to come up
with a more accurate specification. The 4 ranges below are basically
the result of this exclusion:
> > * GPIO Output + GPIO Input + GPIO Data
> > * Multiplexing Control
> > * PAD Pull Control + PAD Schmitt Trigger enable + PAD Control
> > * PAD Drive Capacity Select
>
> The h/w sometimes has these and sometimes doesn't?
No, the h/w is fixed, the only reason of this approach was to allow a
precise memory region specification, as explained above.
I'm not sure if this should be made mandatory or it's also fine to let
(a lazy) user provide combined ranges or just a contiguous one (like
in the example), with the drawback of loosing the accuracy, of course.
> If they do stay, then you want:
>
> items:
> - description: GPIO Output + GPIO Input + GPIO Data
> - description: ...
Would this be applicable even if we keep this flexible approach and
don't set 'minItems: 4'?
> >
> > > > +
> > > > + clocks:
> > > > + maxItems: 1
> > > > +
> > > > + gpio-controller: true
> > > > +
> > > > + gpio-ranges:
> > > > + maxItems: 1
> > > > +
> > > > + '#gpio-cells':
> > > > + description:
> > > > + Specifies the pin number and flags, as defined in
> > > > + include/dt-bindings/gpio/gpio.h
> > > > + const: 2
> > > > +
> > > > + interrupt-controller: true
> > > > +
> > > > + '#interrupt-cells':
> > > > + description:
> > > > + Specifies the pin number and flags, as defined in
> > > > + include/dt-bindings/interrupt-controller/irq.h
> > > > + const: 2
> > > > +
> > > > + interrupts:
> > > > + description:
> > > > + One interrupt per each of the 5 GPIO ports supported by the controller,
> > > > + sorted by port number ascending order.
> > > > + minItems: 5
> > > > + maxItems: 5
> > > > +
> > > > +patternProperties:
> > > > + '^.*$':
> > > > + if:
> > > > + type: object
> > >
> > > For a new binding, can you do '-pins$' for the node names so we don't
> > > need this if/then hack.
> >
> > Right, the idea was to be consistent with the existing bindings for
> > S700 and S900, which allow free node names, although they are not yet
> > converted to yaml format.
>
> If we want consistency, those should have their node names updated.
Fair enough, I have already updated the node names to use the '-pins'
suffix.
> >
> > > > + then:
> > > > + patternProperties:
> > > > + 'pinmux$':
> > >
> > > Is this really a pattern? Can't tell from the example.
> >
> > pinmux and pinconf subnodes may appear multiple times, that's why I
> > decided to match their names based on the suffix.
> >
> > The example is not complex enough, I will change it to the following:
> >
> > mmc0_default: mmc0_default {
> > pinmux {
> > groups = "sd0_d0_mfp", "sd0_d1_mfp", "sd0_d2_d3_mfp",
> > "sd0_cmd_mfp", "sd0_clk_mfp";
> > function = "sd0";
> > };
> >
> > drv_pinconf {
>
> drv-pinconf
>
> Make the pattern '-?pinconf' to enforce that. (that '-' may need escaping?)
Actually the pattern should be '^(.*-)?pinconf$', to restrict the names
to either 'pinconf' or '<label>-pinconf'.
I have just made some more validation tests and noticed I had missed an
'additionalProperties: false' line, for the 'pins' node. Should be fine
now!
Thanks,
Cristi
^ permalink raw reply
* Re: [PATCH v4 1/2] kernel: Implement selective syscall userspace redirection
From: Kees Cook @ 2020-07-16 21:26 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Gabriel Krisman Bertazi, tglx, linux-kernel, kernel, luto,
gofmanp, linux-kselftest, shuah
In-Reply-To: <20200716210601.GN12769@casper.infradead.org>
On Thu, Jul 16, 2020 at 10:06:01PM +0100, Matthew Wilcox wrote:
> On Thu, Jul 16, 2020 at 03:31:40PM -0400, Gabriel Krisman Bertazi wrote:
> > selector is an optional pointer to a char-sized userspace memory region
> > that has a key switch for the mechanism. This key switch is set to
> > either PR_SYS_DISPATCH_ON, PR_SYS_DISPATCH_OFF to enable and disable the
> > redirection without calling the kernel.
> >
> > The feature is meant to be set per-thread and it is disabled on
> > fork/clone/execv.
>
> Disabled on exec. Disabled in the child on clone/fork (and vfork, I
> think).
>
> That means we don't need to worry about it interacting badly with
> a setuid program, right?
Right, that's the intention.
--
Kees Cook
^ permalink raw reply
* Re: [gpio:ib-for-each-clump 4/4] include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
From: Andy Shevchenko @ 2020-07-16 21:25 UTC (permalink / raw)
To: kernel test robot
Cc: Syed Nayyar Waris, kbuild-all, open list:GPIO SUBSYSTEM,
Linus Walleij
In-Reply-To: <202007170339.nHjeGJBw%lkp@intel.com>
On Thu, Jul 16, 2020 at 11:13 PM kernel test robot <lkp@intel.com> wrote:
>
> tree: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git ib-for-each-clump
> head: 3358c938236d6a1be51124fbbb2698e50689d382
> commit: 3358c938236d6a1be51124fbbb2698e50689d382 [4/4] gpio: xilinx: Utilize generic bitmap_get_value and _set_value.
> config: alpha-randconfig-s031-20200716 (attached as .config)
> compiler: alpha-linux-gcc (GCC) 9.3.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # apt-get install sparse
> # sparse version: v0.6.2-49-g707c5017-dirty
> git checkout 3358c938236d6a1be51124fbbb2698e50689d382
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=alpha
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
>
> sparse warnings: (new ones prefixed by >>)
>
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> include/linux/bitmap.h:594:63: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:638:17: sparse: sparse: invalid access past the end of 'old' (8 8)
>
> vim +639 include/linux/bitmap.h
>
> 169c474fb22d8a5 William Breathitt Gray 2019-12-04 613
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 614 /**
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 615 * bitmap_set_value - set n-bit value within a memory region
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 616 * @map: address to the bitmap memory region
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 617 * @value: value of nbits
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 618 * @start: bit offset of the n-bit value
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 619 * @nbits: size of value in bits
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 620 */
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 621 static inline void bitmap_set_value(unsigned long *map,
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 622 unsigned long value,
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 623 unsigned long start, unsigned long nbits)
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 624 {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 625 const size_t index = BIT_WORD(start);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 626 const unsigned long offset = start % BITS_PER_LONG;
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 627 const unsigned long ceiling = roundup(start + 1, BITS_PER_LONG);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 628 const unsigned long space = ceiling - start;
If start == 0:
index = 0, offset = 0, ceiling = 64, space = 64
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 629
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 630 value &= GENMASK(nbits - 1, 0);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 631
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 632 if (space >= nbits) {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 633 map[index] &= ~(GENMASK(nbits + offset - 1, offset));
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 634 map[index] |= value << offset;
if nbits > space...
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 635 } else {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 636 map[index] &= ~BITMAP_FIRST_WORD_MASK(start);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 637 map[index] |= value << offset;
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 @638 map[index + 1] &= ~BITMAP_LAST_WORD_MASK(start + nbits);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 @639 map[index + 1] |= (value >> space);
space = 64...
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 640 }
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 641 }
I don't see the test case for this. Can you provide one?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [gpio:ib-for-each-clump 4/4] include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
From: Andy Shevchenko @ 2020-07-16 21:25 UTC (permalink / raw)
To: kbuild-all
In-Reply-To: <202007170339.nHjeGJBw%lkp@intel.com>
[-- Attachment #1: Type: text/plain, Size: 4671 bytes --]
On Thu, Jul 16, 2020 at 11:13 PM kernel test robot <lkp@intel.com> wrote:
>
> tree: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git ib-for-each-clump
> head: 3358c938236d6a1be51124fbbb2698e50689d382
> commit: 3358c938236d6a1be51124fbbb2698e50689d382 [4/4] gpio: xilinx: Utilize generic bitmap_get_value and _set_value.
> config: alpha-randconfig-s031-20200716 (attached as .config)
> compiler: alpha-linux-gcc (GCC) 9.3.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # apt-get install sparse
> # sparse version: v0.6.2-49-g707c5017-dirty
> git checkout 3358c938236d6a1be51124fbbb2698e50689d382
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=alpha
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
>
> sparse warnings: (new ones prefixed by >>)
>
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> include/linux/bitmap.h:594:63: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:639:45: sparse: sparse: shift too big (64) for type unsigned long
> >> include/linux/bitmap.h:638:17: sparse: sparse: invalid access past the end of 'old' (8 8)
>
> vim +639 include/linux/bitmap.h
>
> 169c474fb22d8a5 William Breathitt Gray 2019-12-04 613
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 614 /**
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 615 * bitmap_set_value - set n-bit value within a memory region
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 616 * @map: address to the bitmap memory region
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 617 * @value: value of nbits
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 618 * @start: bit offset of the n-bit value
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 619 * @nbits: size of value in bits
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 620 */
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 621 static inline void bitmap_set_value(unsigned long *map,
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 622 unsigned long value,
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 623 unsigned long start, unsigned long nbits)
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 624 {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 625 const size_t index = BIT_WORD(start);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 626 const unsigned long offset = start % BITS_PER_LONG;
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 627 const unsigned long ceiling = roundup(start + 1, BITS_PER_LONG);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 628 const unsigned long space = ceiling - start;
If start == 0:
index = 0, offset = 0, ceiling = 64, space = 64
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 629
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 630 value &= GENMASK(nbits - 1, 0);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 631
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 632 if (space >= nbits) {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 633 map[index] &= ~(GENMASK(nbits + offset - 1, offset));
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 634 map[index] |= value << offset;
if nbits > space...
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 635 } else {
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 636 map[index] &= ~BITMAP_FIRST_WORD_MASK(start);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 637 map[index] |= value << offset;
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 @638 map[index + 1] &= ~BITMAP_LAST_WORD_MASK(start + nbits);
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 @639 map[index + 1] |= (value >> space);
space = 64...
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 640 }
> e77c9b6f35c4bdf Syed Nayyar Waris 2020-06-27 641 }
I don't see the test case for this. Can you provide one?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: how does the caching works in bcachefs
From: Nix @ 2020-07-16 21:07 UTC (permalink / raw)
To: kent.overstreet; +Cc: Stefan K, linux-bcache, linux-bcachefs
In-Reply-To: <20200709160805.GA158619@zaphod.evilpiepirate.org>
On 9 Jul 2020, kent overstreet told this:
> In real world mixed workloads LRU is fine, it's not that much of a difference
> vs. the more sophisticated algorithms. More important is the stuff like
> sequential_bypass or some other kind of knob to ensure your backup process
> doesn't blow away the entire cache.
The ioprio thing that never got integrated into bcache (but is still
available as out-of-tree patches that work fine) is even better for
this: yes, it might not quite be what ioprio was meant for, but it means
the user has the equivalent of 'nocache' that they can apply to entire
process hierarchies that they don't want to pollute the cache, just by
using ionice. Run your backup with ionice -c 3 and now everything, even
the metadata reads, comes from the cache if it's already in the cache
but otherwise stays out of cache.
(This matters if you have a huge amount of metadata that is rarely read
except when the backup sweeps over it, and a not-too-huge cache device.
You don't want to waste cache space on stuff that only the backup is
accessing...)
^ permalink raw reply
* Re: [PATCH 0/3] Modernize tasklet callback API
From: Kees Cook @ 2020-07-16 21:24 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Peter Zijlstra, Greg Kroah-Hartman, Thomas Gleixner, Allen Pais,
Oscar Carter, Romain Perier, Kevin Curtis, David S. Miller,
Jakub Kicinski, Harald Freudenberger, Heiko Carstens,
Vasily Gorbik, Christian Borntraeger, Jiri Slaby, Felipe Balbi,
Jason Wessel, Daniel Thompson, Douglas Anderson,
Mitchell Blank Jr, Julian Wiedmann, Karsten Graul, Ursula Braun,
Jaroslav Kysela, Takashi Iwai, Christian Gromm, Nishka Dasgupta,
Masahiro Yamada, Stephen Boyd, Matthew Wilcox (Oracle),
Wambui Karuga, Guenter Roeck, Chris Packham, Kyungtae Kim,
Kuppuswamy Sathyanarayanan, Sebastian Andrzej Siewior,
Rafael J. Wysocki, Jonathan Corbet, Will Deacon,
linux-input@vger.kernel.org, lkml, netdev, linux-s390, devel,
USB list, kgdb-bugreport, alsa-devel@alsa-project.org,
kernel-hardening
In-Reply-To: <CAKdAkRQHRobiG-RpifyrAmV9ENgENn_woPBVXpRrhKwRBf9Esw@mail.gmail.com>
On Thu, Jul 16, 2020 at 01:48:20PM -0700, Dmitry Torokhov wrote:
> On Thu, Jul 16, 2020 at 12:14 PM Kees Cook <keescook@chromium.org> wrote:
> >
> > On Thu, Jul 16, 2020 at 09:57:18AM +0200, Peter Zijlstra wrote:
> > > On Wed, Jul 15, 2020 at 08:08:44PM -0700, Kees Cook wrote:
> > > > Hi,
> > > >
> > > > This is the infrastructure changes to prepare the tasklet API for
> > > > conversion to passing the tasklet struct as the callback argument instead
> > > > of an arbitrary unsigned long. The first patch details why this is useful
> > > > (it's the same rationale as the timer_struct changes from a bit ago:
> > > > less abuse during memory corruption attacks, more in line with existing
> > > > ways of doing things in the kernel, save a little space in struct,
> > > > etc). Notably, the existing tasklet API use is much less messy, so there
> > > > is less to clean up.
> > >
> > > I would _MUCH_ rather see tasklets go the way of the dodo, esp. given
> > > that:
> > >
> > > > drivers/input/keyboard/omap-keypad.c | 2 +-
> > > > drivers/input/serio/hil_mlc.c | 2 +-
> > > > drivers/net/wan/farsync.c | 4 +--
> > > > drivers/s390/crypto/ap_bus.c | 2 +-
> > > > drivers/staging/most/dim2/dim2.c | 2 +-
> > > > drivers/staging/octeon/ethernet-tx.c | 2 +-
> > > > drivers/tty/vt/keyboard.c | 2 +-
> > > > drivers/usb/gadget/udc/snps_udc_core.c | 6 ++---
> > > > drivers/usb/host/fhci-sched.c | 2 +-
> > > > include/linux/interrupt.h | 37 ++++++++++++++++++++++----
> > > > kernel/backtracetest.c | 2 +-
> > > > kernel/debug/debug_core.c | 2 +-
> > > > kernel/irq/resend.c | 2 +-
> > > > kernel/softirq.c | 18 ++++++++++++-
> > > > net/atm/pppoatm.c | 2 +-
> > > > net/iucv/iucv.c | 2 +-
> > > > sound/drivers/pcsp/pcsp_lib.c | 2 +-
> > > > 17 files changed, 66 insertions(+), 25 deletions(-)
> > >
> > > there appear to be hardly any users left.. Can't we stage an extinction
> > > event here instead?
> >
> > Oh, I wish, but no. That's just the ones using DECLARE_TASKLET. There
> > are hundred(s?) more (see the referenced tree).
>
> Still, do we really need tasklets? Can we substitute timers executing
> immediately in their place?
If there is a direct replacement, then sure, I'd be happy to do
whatever, however it does not look mechanical to me. If there is a
mechanical way that will convert these two directories (as an example of
various complexities):
drivers/crypto/ccp/
drivers/gpu/drm/i915/gt/
then let's get it documented. But if not, let's write up a paragraph for
the deprecated.rst, mark it as deprecated in comments, and modernize the
API (which is a mostly mechanical change) to avoid it being a problem
for CFI, for memory corruption, and heap space, etc.
--
Kees Cook
^ permalink raw reply
* Re: [PATCH v3 07/12] ppc64/kexec_file: add support to relocate purgatory
From: Hari Bathini @ 2020-07-16 21:11 UTC (permalink / raw)
To: Thiago Jung Bauermann
Cc: kernel test robot, Pingfan Liu, Petr Tesarik, Nayna Jain,
Kexec-ml, Mahesh J Salgaonkar, Mimi Zohar, lkml, linuxppc-dev,
Sourabh Jain, Andrew Morton, Dave Young, Vivek Goyal,
Eric Biederman
In-Reply-To: <871rlc9upc.fsf@morokweng.localdomain>
On 16/07/20 5:50 am, Thiago Jung Bauermann wrote:
>
> Hari Bathini <hbathini@linux.ibm.com> writes:
>
>> Right now purgatory implementation is only minimal. But if purgatory
>> code is to be enhanced to copy memory to the backup region and verify
>
> Can't the memcpy be done in asm? We have arch/powerpc/lib/memcpy_64.S
> for example, perhaps it could be linked in with the purgatory?
I wanted to avoid touching common code to make it work for purgatory
for now.
>
>> sha256 digest, relocations may have to be applied to the purgatory.
>
> Do we want to do the sha256 verification? My original patch series for
> kexec_file_load() had a purgatory in C from kexec-tools which did the
> sha256 verification but Michael Ellerman thought it was unnecessary and
> decided to use the simpler purgatory in asm from kexec-lite.
kexec_file_load could as well be used without IMA or secureboot. With sha256 digest
calculated anyway, verifying it would make sense to accommodate that case as well.
>
>> So, add support to relocate purgatory in kexec_file_load system call
>> by setting up TOC pointer and applying RELA relocations as needed.
>
> If we do want to use a C purgatory, Michael Ellerman had suggested
> building it as a Position Independent Executable, which greatly reduces
> the number and types of relocations that are needed. See patches 4 and 9
> here:
>
> https://lore.kernel.org/linuxppc-dev/1478748449-3894-1-git-send-email-bauerman@linux.vnet.ibm.com/
>
> In the series above I hadn't converted x86 to PIE. If I had done that,
> possibly Dave Young's opinion would have been different. :-)
>
> If that's still not desirable, he suggested in that discussion lifting
> some code from x86 to generic code, which I implemented and would
> simplify this patch as well:
>
> https://lore.kernel.org/linuxppc-dev/5009580.5GxAkTrMYA@morokweng/
>
Agreed. But I prefer to work on PIE and/or moving common relocation_add code
for x86 & s390 to generic code later when I try to build on these purgatory
changes. So, a separate series later to rework purgatory with the things you
mentioned above sounds ok?
Thanks
Hari
^ permalink raw reply
* Re: [RFC PATCH 4/7] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Alan Stern @ 2020-07-16 21:24 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Nicholas Piggin, paulmck, Anton Blanchard, Arnd Bergmann,
linux-arch, linux-kernel, linux-mm, linuxppc-dev, Andy Lutomirski,
Peter Zijlstra, x86
In-Reply-To: <595582123.17106.1594925921537.JavaMail.zimbra@efficios.com>
On Thu, Jul 16, 2020 at 02:58:41PM -0400, Mathieu Desnoyers wrote:
> ----- On Jul 16, 2020, at 12:03 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote:
>
> > ----- On Jul 16, 2020, at 11:46 AM, Mathieu Desnoyers
> > mathieu.desnoyers@efficios.com wrote:
> >
> >> ----- On Jul 16, 2020, at 12:42 AM, Nicholas Piggin npiggin@gmail.com wrote:
> >>> I should be more complete here, especially since I was complaining
> >>> about unclear barrier comment :)
> >>>
> >>>
> >>> CPU0 CPU1
> >>> a. user stuff 1. user stuff
> >>> b. membarrier() 2. enter kernel
> >>> c. smp_mb() 3. smp_mb__after_spinlock(); // in __schedule
> >>> d. read rq->curr 4. rq->curr switched to kthread
> >>> e. is kthread, skip IPI 5. switch_to kthread
> >>> f. return to user 6. rq->curr switched to user thread
> >>> g. user stuff 7. switch_to user thread
> >>> 8. exit kernel
> >>> 9. more user stuff
> >>>
> >>> What you're really ordering is a, g vs 1, 9 right?
> >>>
> >>> In other words, 9 must see a if it sees g, g must see 1 if it saw 9,
> >>> etc.
> >>>
> >>> Userspace does not care where the barriers are exactly or what kernel
> >>> memory accesses might be being ordered by them, so long as there is a
> >>> mb somewhere between a and g, and 1 and 9. Right?
> >>
> >> This is correct.
> >
> > Actually, sorry, the above is not quite right. It's been a while
> > since I looked into the details of membarrier.
> >
> > The smp_mb() at the beginning of membarrier() needs to be paired with a
> > smp_mb() _after_ rq->curr is switched back to the user thread, so the
> > memory barrier is between store to rq->curr and following user-space
> > accesses.
> >
> > The smp_mb() at the end of membarrier() needs to be paired with the
> > smp_mb__after_spinlock() at the beginning of schedule, which is
> > between accesses to userspace memory and switching rq->curr to kthread.
> >
> > As to *why* this ordering is needed, I'd have to dig through additional
> > scenarios from https://lwn.net/Articles/573436/. Or maybe Paul remembers ?
>
> Thinking further about this, I'm beginning to consider that maybe we have been
> overly cautious by requiring memory barriers before and after store to rq->curr.
>
> If CPU0 observes a CPU1's rq->curr->mm which differs from its own process (current)
> while running the membarrier system call, it necessarily means that CPU1 had
> to issue smp_mb__after_spinlock when entering the scheduler, between any user-space
> loads/stores and update of rq->curr.
>
> Requiring a memory barrier between update of rq->curr (back to current process's
> thread) and following user-space memory accesses does not seem to guarantee
> anything more than what the initial barrier at the beginning of __schedule already
> provides, because the guarantees are only about accesses to user-space memory.
>
> Therefore, with the memory barrier at the beginning of __schedule, just observing that
> CPU1's rq->curr differs from current should guarantee that a memory barrier was issued
> between any sequentially consistent instructions belonging to the current process on
> CPU1.
>
> Or am I missing/misremembering an important point here ?
Is it correct to say that the switch_to operations in 5 and 7 include
memory barriers? If they do, then skipping the IPI should be okay.
The reason is as follows: The guarantee you need to enforce is that
anything written by CPU0 before the membarrier() will be visible to CPU1
after it returns to user mode. Let's say that a writes to X and 9
reads from X.
Then we have an instance of the Store Buffer pattern:
CPU0 CPU1
a. Write X 6. Write rq->curr for user thread
c. smp_mb() 7. switch_to memory barrier
d. Read rq->curr 9. Read X
In this pattern, the memory barriers make it impossible for both reads
to miss their corresponding writes. Since d does fail to read 6 (it
sees the earlier value stored by 4), 9 must read a.
The other guarantee you need is that g on CPU0 will observe anything
written by CPU1 in 1. This is easier to see, using the fact that 3 is a
memory barrier and d reads from 4.
Alan Stern
^ permalink raw reply
* [PATCH v3 27/27] drm/amd/display: enable SI support in the Kconfig (v2)
From: Mauro Rossi @ 2020-07-16 21:22 UTC (permalink / raw)
To: amd-gfx; +Cc: alexander.deucher, Mauro Rossi, harry.wentland
In-Reply-To: <20200716212251.1539094-1-issor.oruam@gmail.com>
[Why]
All DCE6 specific code changes are guarded by CONFIG_DRM_AMD_DC_SI Kconfig option
[How]
(v1) CONFIG_DRM_AMD_DC_SI configuration option is added, default setting is disabled
(v2) Hainan is not supported, description updated accordingly
Tested with HD7750 (Cape Verde) and HD7950 (Tahiti)
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
---
drivers/gpu/drm/amd/display/Kconfig | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 34ae4f3a32f4..77569097a480 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -31,6 +31,14 @@ config DRM_AMD_DC_HDCP
help
Choose this option if you want to support HDCP authentication.
+config DRM_AMD_DC_SI
+ bool "AMD DC support for Southern Islands ASICs"
+ default n
+ help
+ Choose this option to enable new AMD DC support for SI asics
+ by default. This includes Tahiti, Pitcairn, Cape Verde, Oland.
+ Hainan is not supported by AMD DC and it has no physical DCE6.
+
config DEBUG_KERNEL_DC
bool "Enable kgdb break in DC"
depends on DRM_AMD_DC
--
2.25.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH v3 21/27] drm/amd/display: dce60_hw_sequencer: add DCE6 specific functions
From: Mauro Rossi @ 2020-07-16 21:22 UTC (permalink / raw)
To: amd-gfx; +Cc: alexander.deucher, Mauro Rossi, harry.wentland
In-Reply-To: <20200716212251.1539094-1-issor.oruam@gmail.com>
[Why]
DCE6 has no bottom_pipe and no Blender HW
DCE6 needs 'blank_target' set to false in order to turn on the display
DCE6 has a specific dce60_pipe_control_lock() fuction that is a no op
[How]
Add DCE6 specific functions with needed private dce60_* dependent fuctions
Comment DCE6 specific CTRC program visibility implementation
Fix a typo in the initial header includes comment 's/DCE8/DCE6/g'
Use dce60_apply_ctx_for_surface() in dce60_hw_sequencer_construct
Use dce60_pipe_control_lock() in dce60_hw_sequencer_construct
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
---
.../amd/display/dc/dce60/dce60_hw_sequencer.c | 381 +++++++++++++++++-
1 file changed, 379 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c
index e30e3510ec4a..37bd91883926 100644
--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c
@@ -32,22 +32,399 @@
#include "dce110/dce110_hw_sequencer.h"
#include "dce100/dce100_hw_sequencer.h"
-/* include DCE8 register header files */
+/* include DCE6 register header files */
#include "dce/dce_6_0_d.h"
#include "dce/dce_6_0_sh_mask.h"
+#define DC_LOGGER_INIT()
+
/*******************************************************************************
* Private definitions
******************************************************************************/
/***************************PIPE_CONTROL***********************************/
+/*
+ * Check if FBC can be enabled
+ */
+static bool dce60_should_enable_fbc(struct dc *dc,
+ struct dc_state *context,
+ uint32_t *pipe_idx)
+{
+ uint32_t i;
+ struct pipe_ctx *pipe_ctx = NULL;
+ struct resource_context *res_ctx = &context->res_ctx;
+ unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
+
+
+ ASSERT(dc->fbc_compressor);
+
+ /* FBC memory should be allocated */
+ if (!dc->ctx->fbc_gpu_addr)
+ return false;
+
+ /* Only supports single display */
+ if (context->stream_count != 1)
+ return false;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (res_ctx->pipe_ctx[i].stream) {
+
+ pipe_ctx = &res_ctx->pipe_ctx[i];
+
+ if (!pipe_ctx)
+ continue;
+
+ /* fbc not applicable on underlay pipe */
+ if (pipe_ctx->pipe_idx != underlay_idx) {
+ *pipe_idx = i;
+ break;
+ }
+ }
+ }
+
+ if (i == dc->res_pool->pipe_count)
+ return false;
+
+ if (!pipe_ctx->stream->link)
+ return false;
+
+ /* Only supports eDP */
+ if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
+ return false;
+
+ /* PSR should not be enabled */
+ if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
+ return false;
+
+ /* Nothing to compress */
+ if (!pipe_ctx->plane_state)
+ return false;
+
+ /* Only for non-linear tiling */
+ if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
+ return false;
+
+ return true;
+}
+
+/*
+ * Enable FBC
+ */
+static void dce60_enable_fbc(
+ struct dc *dc,
+ struct dc_state *context)
+{
+ uint32_t pipe_idx = 0;
+
+ if (dce60_should_enable_fbc(dc, context, &pipe_idx)) {
+ /* Program GRPH COMPRESSED ADDRESS and PITCH */
+ struct compr_addr_and_pitch_params params = {0, 0, 0};
+ struct compressor *compr = dc->fbc_compressor;
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
+
+ params.source_view_width = pipe_ctx->stream->timing.h_addressable;
+ params.source_view_height = pipe_ctx->stream->timing.v_addressable;
+ params.inst = pipe_ctx->stream_res.tg->inst;
+ compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
+
+ compr->funcs->surface_address_and_pitch(compr, ¶ms);
+ compr->funcs->set_fbc_invalidation_triggers(compr, 1);
+
+ compr->funcs->enable_fbc(compr, ¶ms);
+ }
+}
+
+
+/*******************************************************************************
+ * Front End programming
+ ******************************************************************************/
+
+static void dce60_set_default_colors(struct pipe_ctx *pipe_ctx)
+{
+ struct default_adjustment default_adjust = { 0 };
+
+ default_adjust.force_hw_default = false;
+ default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
+ default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
+ default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
+ default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
+
+ /* display color depth */
+ default_adjust.color_depth =
+ pipe_ctx->stream->timing.display_color_depth;
+
+ /* Lb color depth */
+ default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
+
+ pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
+ pipe_ctx->plane_res.xfm, &default_adjust);
+}
+
+/*******************************************************************************
+ * In order to turn on surface we will program
+ * CRTC
+ *
+ * DCE6 has no bottom_pipe and no Blender HW
+ * We need to set 'blank_target' to false in order to turn on the display
+ *
+ * |-----------|------------|---------|
+ * |curr pipe | set_blank | |
+ * |Surface |blank_target| CRCT |
+ * |visibility | argument | |
+ * |-----------|------------|---------|
+ * | off | true | blank |
+ * | on | false | unblank |
+ * |-----------|------------|---------|
+ *
+ ******************************************************************************/
+static void dce60_program_surface_visibility(const struct dc *dc,
+ struct pipe_ctx *pipe_ctx)
+{
+ bool blank_target = false;
+
+ /* DCE6 has no bottom_pipe and no Blender HW */
+
+ if (!pipe_ctx->plane_state->visible)
+ blank_target = true;
+
+ /* DCE6 skip dce_set_blender_mode() but then proceed to 'unblank' CRTC */
+ pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
+
+}
+
+
+static void dce60_get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,
+ struct tg_color *color)
+{
+ uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4;
+
+ switch (pipe_ctx->plane_res.scl_data.format) {
+ case PIXEL_FORMAT_ARGB8888:
+ /* set boarder color to red */
+ color->color_r_cr = color_value;
+ break;
+
+ case PIXEL_FORMAT_ARGB2101010:
+ /* set boarder color to blue */
+ color->color_b_cb = color_value;
+ break;
+ case PIXEL_FORMAT_420BPP8:
+ /* set boarder color to green */
+ color->color_g_y = color_value;
+ break;
+ case PIXEL_FORMAT_420BPP10:
+ /* set boarder color to yellow */
+ color->color_g_y = color_value;
+ color->color_r_cr = color_value;
+ break;
+ case PIXEL_FORMAT_FP16:
+ /* set boarder color to white */
+ color->color_r_cr = color_value;
+ color->color_b_cb = color_value;
+ color->color_g_y = color_value;
+ break;
+ default:
+ break;
+ }
+}
+
+static void dce60_program_scaler(const struct dc *dc,
+ const struct pipe_ctx *pipe_ctx)
+{
+ struct tg_color color = {0};
+
+ /* DCE6 skips DCN TOFPGA check for transform_set_pixel_storage_depth == NULL */
+
+ if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
+ dce60_get_surface_visual_confirm_color(pipe_ctx, &color);
+ else
+ color_space_to_black_color(dc,
+ pipe_ctx->stream->output_color_space,
+ &color);
+
+ pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
+ pipe_ctx->plane_res.xfm,
+ pipe_ctx->plane_res.scl_data.lb_params.depth,
+ &pipe_ctx->stream->bit_depth_params);
+
+ if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
+ /*
+ * The way 420 is packed, 2 channels carry Y component, 1 channel
+ * alternate between Cb and Cr, so both channels need the pixel
+ * value for Y
+ */
+ if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
+ color.color_r_cr = color.color_g_y;
+
+ pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
+ pipe_ctx->stream_res.tg,
+ &color);
+ }
+
+ pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
+ &pipe_ctx->plane_res.scl_data);
+}
+
+
+dce60_program_front_end_for_pipe(
+ struct dc *dc, struct pipe_ctx *pipe_ctx)
+{
+ struct mem_input *mi = pipe_ctx->plane_res.mi;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ struct xfm_grph_csc_adjustment adjust;
+ struct out_csc_color_matrix tbl_entry;
+ unsigned int i;
+ struct dce_hwseq *hws = dc->hwseq;
+
+ DC_LOGGER_INIT();
+ memset(&tbl_entry, 0, sizeof(tbl_entry));
+
+ memset(&adjust, 0, sizeof(adjust));
+ adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+ dce_enable_fe_clock(dc->hwseq, mi->inst, true);
+
+ dce60_set_default_colors(pipe_ctx);
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
+ == true) {
+ tbl_entry.color_space =
+ pipe_ctx->stream->output_color_space;
+
+ for (i = 0; i < 12; i++)
+ tbl_entry.regval[i] =
+ pipe_ctx->stream->csc_color_matrix.matrix[i];
+
+ pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
+ (pipe_ctx->plane_res.xfm, &tbl_entry);
+ }
+
+ if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
+ adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+ }
+
+ pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
+
+ pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
+
+ dce60_program_scaler(dc, pipe_ctx);
+
+ mi->funcs->mem_input_program_surface_config(
+ mi,
+ plane_state->format,
+ &plane_state->tiling_info,
+ &plane_state->plane_size,
+ plane_state->rotation,
+ NULL,
+ false);
+ if (mi->funcs->set_blank)
+ mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
+
+ if (dc->config.gpu_vm_support)
+ mi->funcs->mem_input_program_pte_vm(
+ pipe_ctx->plane_res.mi,
+ plane_state->format,
+ &plane_state->tiling_info,
+ plane_state->rotation);
+
+ /* Moved programming gamma from dc to hwss */
+ if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+ pipe_ctx->plane_state->update_flags.bits.gamma_change)
+ hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
+
+ if (pipe_ctx->plane_state->update_flags.bits.full_update)
+ hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
+
+ DC_LOG_SURFACE(
+ "Pipe:%d %p: addr hi:0x%x, "
+ "addr low:0x%x, "
+ "src: %d, %d, %d,"
+ " %d; dst: %d, %d, %d, %d;"
+ "clip: %d, %d, %d, %d\n",
+ pipe_ctx->pipe_idx,
+ (void *) pipe_ctx->plane_state,
+ pipe_ctx->plane_state->address.grph.addr.high_part,
+ pipe_ctx->plane_state->address.grph.addr.low_part,
+ pipe_ctx->plane_state->src_rect.x,
+ pipe_ctx->plane_state->src_rect.y,
+ pipe_ctx->plane_state->src_rect.width,
+ pipe_ctx->plane_state->src_rect.height,
+ pipe_ctx->plane_state->dst_rect.x,
+ pipe_ctx->plane_state->dst_rect.y,
+ pipe_ctx->plane_state->dst_rect.width,
+ pipe_ctx->plane_state->dst_rect.height,
+ pipe_ctx->plane_state->clip_rect.x,
+ pipe_ctx->plane_state->clip_rect.y,
+ pipe_ctx->plane_state->clip_rect.width,
+ pipe_ctx->plane_state->clip_rect.height);
+
+ DC_LOG_SURFACE(
+ "Pipe %d: width, height, x, y\n"
+ "viewport:%d, %d, %d, %d\n"
+ "recout: %d, %d, %d, %d\n",
+ pipe_ctx->pipe_idx,
+ pipe_ctx->plane_res.scl_data.viewport.width,
+ pipe_ctx->plane_res.scl_data.viewport.height,
+ pipe_ctx->plane_res.scl_data.viewport.x,
+ pipe_ctx->plane_res.scl_data.viewport.y,
+ pipe_ctx->plane_res.scl_data.recout.width,
+ pipe_ctx->plane_res.scl_data.recout.height,
+ pipe_ctx->plane_res.scl_data.recout.x,
+ pipe_ctx->plane_res.scl_data.recout.y);
+}
+
+static void dce60_apply_ctx_for_surface(
+ struct dc *dc,
+ const struct dc_stream_state *stream,
+ int num_planes,
+ struct dc_state *context)
+{
+ int i;
+
+ if (num_planes == 0)
+ return;
+
+ if (dc->fbc_compressor)
+ dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ if (pipe_ctx->stream != stream)
+ continue;
+
+ /* Need to allocate mem before program front end for Fiji */
+ pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
+ pipe_ctx->plane_res.mi,
+ pipe_ctx->stream->timing.h_total,
+ pipe_ctx->stream->timing.v_total,
+ pipe_ctx->stream->timing.pix_clk_100hz / 10,
+ context->stream_count);
+
+ dce60_program_front_end_for_pipe(dc, pipe_ctx);
+
+ dc->hwss.update_plane_addr(dc, pipe_ctx);
+
+ dce60_program_surface_visibility(dc, pipe_ctx);
+
+ }
+
+ if (dc->fbc_compressor)
+ dce60_enable_fbc(dc, context);
+}
+
void dce60_hw_sequencer_construct(struct dc *dc)
{
dce110_hw_sequencer_construct(dc);
dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
- dc->hwss.pipe_control_lock = dce_pipe_control_lock;
+ dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface;
+ dc->hwss.pipe_control_lock = dce60_pipe_control_lock;
dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
}
--
2.25.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH v3 25/27] drm/amd/display: create plane rotation property for Bonaire and later
From: Mauro Rossi @ 2020-07-16 21:22 UTC (permalink / raw)
To: amd-gfx; +Cc: alexander.deucher, Mauro Rossi, harry.wentland
In-Reply-To: <20200716212251.1539094-1-issor.oruam@gmail.com>
[Why]
DCE6 chipsets do not support HW rotation
[How]
rotation property is created for Bonaire and later
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index df46cf7cb374..25ffa89d5657 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6103,8 +6103,9 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
- drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
- supported_rotations);
+ if (dm->adev->asic_type >= CHIP_BONAIRE)
+ drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
+ supported_rotations);
drm_plane_helper_add(plane, &dm_plane_helper_funcs);
--
2.25.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH v3 26/27] drm/amdgpu: enable DC support for SI parts (v2)
From: Mauro Rossi @ 2020-07-16 21:22 UTC (permalink / raw)
To: amd-gfx; +Cc: alexander.deucher, Mauro Rossi, harry.wentland
In-Reply-To: <20200716212251.1539094-1-issor.oruam@gmail.com>
[Why]
amdgpu_device.c requires changes for SI chipsets support
si.c require changes for Display Manager IP block enabling
[How]
amdgpu_device.c: add SI families in amdgpu_device_asic_has_dc_support()
si.c: changes in si_set_ip_blocks() for Display Manager IP blocks enablement
(v1) NOTE: As per Kaveri and older amdgpu.dc=1 kernel cmdline is required
(v2) fix for bc011f9350 ("drm/amdgpu: Change SI/CI gfx/sdma/smu init sequence")
remove CHIP_HAINAN support since it does not have physical DCE6 module
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 ++++++
drivers/gpu/drm/amd/amdgpu/si.c | 10 ++++++++++
2 files changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index aa5b54e5a1d7..cd5efa6c1c18 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2775,6 +2775,12 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
{
switch (asic_type) {
#if defined(CONFIG_DRM_AMD_DC)
+#if defined(CONFIG_DRM_AMD_DC_SI)
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+#endif
case CHIP_BONAIRE:
case CHIP_KAVERI:
case CHIP_KABINI:
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 1b449291f068..5a112c7a35ca 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -52,6 +52,8 @@
#include "bif/bif_3_0_d.h"
#include "bif/bif_3_0_sh_mask.h"
+#include "amdgpu_dm.h"
+
static const u32 tahiti_golden_registers[] =
{
mmAZALIA_SCLK_CONTROL, 0x00000030, 0x00000011,
@@ -2546,6 +2548,10 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
+ else if (amdgpu_device_has_dc_support(adev))
+ amdgpu_device_ip_block_add(adev, &dm_ip_block);
+#endif
else
amdgpu_device_ip_block_add(adev, &dce_v6_0_ip_block);
amdgpu_device_ip_block_add(adev, &uvd_v3_1_ip_block);
@@ -2560,6 +2566,10 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
if (adev->enable_virtual_display)
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
+#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
+ else if (amdgpu_device_has_dc_support(adev))
+ amdgpu_device_ip_block_add(adev, &dm_ip_block);
+#endif
else
amdgpu_device_ip_block_add(adev, &dce_v6_4_ip_block);
amdgpu_device_ip_block_add(adev, &uvd_v3_1_ip_block);
--
2.25.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH v3 23/27] drm/amd/display: dce60_timing_generator: add DCE6 specific functions
From: Mauro Rossi @ 2020-07-16 21:22 UTC (permalink / raw)
To: amd-gfx; +Cc: alexander.deucher, Mauro Rossi, harry.wentland
In-Reply-To: <20200716212251.1539094-1-issor.oruam@gmail.com>
[Why]
DCE6 has CRTC_PREFETCH_EN bit in CRTC_CONTROL register
DCE6 has no CRTC_LEGACY_REQUESTOR_EN bit in CRTC_START_LINE_CONTROL register
DCE6 has no CRTC_CRC_CNTL register
[How]
Modify dce60_timing_generator_enable_advanced_request() function
Add dce60_configure_crc() function and dce60_is_tg_enabled() kept as static
Use dce60_configure_crc() function in dce60_tg_funcs
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
---
.../display/dc/dce60/dce60_timing_generator.c | 57 +++++++++++++------
.../amd/display/dc/inc/hw/clk_mgr_internal.h | 11 ++++
2 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
index eb9705e9d40a..4a5b7a0940c6 100644
--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
@@ -128,20 +128,12 @@ static void dce60_timing_generator_enable_advanced_request(
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
uint32_t value = dm_read_reg(tg->ctx, addr);
+ /* DCE6 has CRTC_PREFETCH_EN bit in CRTC_CONTROL register */
+ uint32_t addr2 = CRTC_REG(mmCRTC_CONTROL);
+ uint32_t value2 = dm_read_reg(tg->ctx, addr2);
- if (enable) {
- set_reg_field_value(
- value,
- 0,
- CRTC_START_LINE_CONTROL,
- CRTC_LEGACY_REQUESTOR_EN);
- } else {
- set_reg_field_value(
- value,
- 1,
- CRTC_START_LINE_CONTROL,
- CRTC_LEGACY_REQUESTOR_EN);
- }
+ /* DCE6 does not support CRTC_LEGACY_REQUESTOR_EN bit
+ so here is not possible to set bit based on enable argument */
if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
set_reg_field_value(
@@ -150,9 +142,9 @@ static void dce60_timing_generator_enable_advanced_request(
CRTC_START_LINE_CONTROL,
CRTC_ADVANCED_START_LINE_POSITION);
set_reg_field_value(
- value,
+ value2,
0,
- CRTC_START_LINE_CONTROL,
+ CRTC_CONTROL,
CRTC_PREFETCH_EN);
} else {
set_reg_field_value(
@@ -161,9 +153,9 @@ static void dce60_timing_generator_enable_advanced_request(
CRTC_START_LINE_CONTROL,
CRTC_ADVANCED_START_LINE_POSITION);
set_reg_field_value(
- value,
+ value2,
1,
- CRTC_START_LINE_CONTROL,
+ CRTC_CONTROL,
CRTC_PREFETCH_EN);
}
@@ -180,6 +172,35 @@ static void dce60_timing_generator_enable_advanced_request(
CRTC_INTERLACE_START_LINE_EARLY);
dm_write_reg(tg->ctx, addr, value);
+ dm_write_reg(tg->ctx, addr2, value2);
+}
+
+static bool dce60_is_tg_enabled(struct timing_generator *tg)
+{
+ uint32_t addr = 0;
+ uint32_t value = 0;
+ uint32_t field = 0;
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+ addr = CRTC_REG(mmCRTC_CONTROL);
+ value = dm_read_reg(tg->ctx, addr);
+ field = get_reg_field_value(value, CRTC_CONTROL,
+ CRTC_CURRENT_MASTER_EN_STATE);
+ return field == 1;
+}
+
+bool dce60_configure_crc(struct timing_generator *tg,
+ const struct crc_params *params)
+{
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+ /* Cannot configure crc on a CRTC that is disabled */
+ if (!dce60_is_tg_enabled(tg))
+ return false;
+
+ /* DCE6 has no CRTC_CRC_CNTL register, nothing to do */
+
+ return true;
}
static const struct timing_generator_funcs dce60_tg_funcs = {
@@ -217,7 +238,7 @@ static const struct timing_generator_funcs dce60_tg_funcs = {
/* DCE6.0 overrides */
.enable_advanced_request =
dce60_timing_generator_enable_advanced_request,
- .configure_crc = dce110_configure_crc,
+ .configure_crc = dce60_configure_crc,
.get_crc = dce110_get_crc,
};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
index 4e6e18bbef5d..ca9eedb643f2 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -88,6 +88,11 @@ enum dentist_divider_range {
.DPREFCLK_CNTL = mmDPREFCLK_CNTL, \
.DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL
+#if defined(CONFIG_DRM_AMD_DC_SI)
+#define CLK_COMMON_REG_LIST_DCE60_BASE() \
+ SR(DENTIST_DISPCLK_CNTL)
+#endif
+
#define CLK_COMMON_REG_LIST_DCN_BASE() \
SR(DENTIST_DISPCLK_CNTL)
@@ -114,6 +119,12 @@ enum dentist_divider_range {
CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \
CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh)
+#if defined(CONFIG_DRM_AMD_DC_SI)
+#define CLK_COMMON_MASK_SH_LIST_DCE60_COMMON_BASE(mask_sh) \
+ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
+ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
+#endif
+
#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \
CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
--
2.25.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.