From: Sasha Levin Date: Sun, 23 Feb 2025 17:23:13 +0000 (-0500) Subject: Fixes for 6.6 X-Git-Tag: v6.6.80~25^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=030a5e6e749e4b79d6ea0eb1512ded142527f51d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch b/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch new file mode 100644 index 0000000000..0b163bc683 --- /dev/null +++ b/queue-6.6/arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch @@ -0,0 +1,45 @@ +From a7a53fbe96a86c27a6420adbdaf06842b66352eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Oct 2024 15:56:28 +0800 +Subject: arm64: dts: mediatek: mt8183: Disable DSI display output by default + +From: Chen-Yu Tsai + +[ Upstream commit 26f6e91fa29a58fdc76b47f94f8f6027944a490c ] + +Most SoC dtsi files have the display output interfaces disabled by +default, and only enabled on boards that utilize them. The MT8183 +has it backwards: the display outputs are left enabled by default, +and only disabled at the board level. + +Reverse the situation for the DSI output so that it follows the +normal scheme. For ease of backporting the DPI output is handled +in a separate patch. + +Fixes: 88ec840270e6 ("arm64: dts: mt8183: Add dsi node") +Fixes: 19b6403f1e2a ("arm64: dts: mt8183: add mt8183 pumpkin board") +Cc: stable@vger.kernel.org +Signed-off-by: Chen-Yu Tsai +Reviewed-by: Fei Shao +Link: https://lore.kernel.org/r/20241025075630.3917458-2-wenst@chromium.org +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index d1b6355148620..f3a1b96f1ee4d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1828,6 +1828,7 @@ dsi0: dsi@14014000 { + resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>; + phys = <&mipi_tx0>; + phy-names = "dphy"; ++ status = "disabled"; + }; + + mutex: mutex@14016000 { +-- +2.39.5 + diff --git a/queue-6.6/bpf-avoid-holding-freeze_mutex-during-mmap-operation.patch b/queue-6.6/bpf-avoid-holding-freeze_mutex-during-mmap-operation.patch new file mode 100644 index 0000000000..db9fe05708 --- /dev/null +++ b/queue-6.6/bpf-avoid-holding-freeze_mutex-during-mmap-operation.patch @@ -0,0 +1,79 @@ +From 491e2a0b4fe8b036ad4b4e0763321eada17fdf13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 17:22:46 -0800 +Subject: bpf: avoid holding freeze_mutex during mmap operation + +From: Andrii Nakryiko + +[ Upstream commit bc27c52eea189e8f7492d40739b7746d67b65beb ] + +We use map->freeze_mutex to prevent races between map_freeze() and +memory mapping BPF map contents with writable permissions. The way we +naively do this means we'll hold freeze_mutex for entire duration of all +the mm and VMA manipulations, which is completely unnecessary. This can +potentially also lead to deadlocks, as reported by syzbot in [0]. + +So, instead, hold freeze_mutex only during writeability checks, bump +(proactively) "write active" count for the map, unlock the mutex and +proceed with mmap logic. And only if something went wrong during mmap +logic, then undo that "write active" counter increment. + + [0] https://lore.kernel.org/bpf/678dcbc9.050a0220.303755.0066.GAE@google.com/ + +Fixes: fc9702273e2e ("bpf: Add mmap() support for BPF_MAP_TYPE_ARRAY") +Reported-by: syzbot+4dc041c686b7c816a71e@syzkaller.appspotmail.com +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20250129012246.1515826-2-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 98d7558e2f2be..9f791b6b09edc 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -882,7 +882,7 @@ static const struct vm_operations_struct bpf_map_default_vmops = { + static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + { + struct bpf_map *map = filp->private_data; +- int err; ++ int err = 0; + + if (!map->ops->map_mmap || !IS_ERR_OR_NULL(map->record)) + return -ENOTSUPP; +@@ -906,7 +906,12 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + err = -EACCES; + goto out; + } ++ bpf_map_write_active_inc(map); + } ++out: ++ mutex_unlock(&map->freeze_mutex); ++ if (err) ++ return err; + + /* set default open/close callbacks */ + vma->vm_ops = &bpf_map_default_vmops; +@@ -923,13 +928,11 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + vm_flags_clear(vma, VM_MAYWRITE); + + err = map->ops->map_mmap(map, vma); +- if (err) +- goto out; ++ if (err) { ++ if (vma->vm_flags & VM_WRITE) ++ bpf_map_write_active_dec(map); ++ } + +- if (vma->vm_flags & VM_WRITE) +- bpf_map_write_active_inc(map); +-out: +- mutex_unlock(&map->freeze_mutex); + return err; + } + +-- +2.39.5 + diff --git a/queue-6.6/bpf-disable-non-stream-socket-for-strparser.patch b/queue-6.6/bpf-disable-non-stream-socket-for-strparser.patch new file mode 100644 index 0000000000..ad9ad932bb --- /dev/null +++ b/queue-6.6/bpf-disable-non-stream-socket-for-strparser.patch @@ -0,0 +1,51 @@ +From f71318cfccb8c7ab2bea3369ee71e3adbf9e3dab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 18:09:15 +0800 +Subject: bpf: Disable non stream socket for strparser + +From: Jiayuan Chen + +[ Upstream commit 5459cce6bf49e72ee29be21865869c2ac42419f5 ] + +Currently, only TCP supports strparser, but sockmap doesn't intercept +non-TCP connections to attach strparser. For example, with UDP, although +the read/write handlers are replaced, strparser is not executed due to +the lack of a read_sock operation. + +Furthermore, in udp_bpf_recvmsg(), it checks whether the psock has data, +and if not, it falls back to the native UDP read interface, making +UDP + strparser appear to read correctly. According to its commit history, +this behavior is unexpected. + +Moreover, since UDP lacks the concept of streams, we intercept it directly. + +Fixes: 1fa1fe8ff161 ("bpf, sockmap: Test shutdown() correctly exits epoll and recv()=0") +Signed-off-by: Jiayuan Chen +Signed-off-by: Martin KaFai Lau +Acked-by: Jakub Sitnicki +Acked-by: John Fastabend +Link: https://patch.msgid.link/20250122100917.49845-4-mrpre@163.com +Signed-off-by: Sasha Levin +--- + net/core/sock_map.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index dcc0f31a17a8d..3a53b6a0e76e2 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -300,7 +300,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) + + write_lock_bh(&sk->sk_callback_lock); + if (stream_parser && stream_verdict && !psock->saved_data_ready) { +- ret = sk_psock_init_strp(sk, psock); ++ if (sk_is_tcp(sk)) ++ ret = sk_psock_init_strp(sk, psock); ++ else ++ ret = -EOPNOTSUPP; + if (ret) { + write_unlock_bh(&sk->sk_callback_lock); + sk_psock_put(sk, psock); +-- +2.39.5 + diff --git a/queue-6.6/bpf-fix-deadlock-when-freeing-cgroup-storage.patch b/queue-6.6/bpf-fix-deadlock-when-freeing-cgroup-storage.patch new file mode 100644 index 0000000000..74c8cbd0fc --- /dev/null +++ b/queue-6.6/bpf-fix-deadlock-when-freeing-cgroup-storage.patch @@ -0,0 +1,95 @@ +From 3a421d7a48a3a7fc2b5b0867588f1d56bcfb6e82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Dec 2024 14:10:16 +0800 +Subject: bpf: Fix deadlock when freeing cgroup storage + +From: Abel Wu + +[ Upstream commit c78f4afbd962f43a3989f45f3ca04300252b19b5 ] + +The following commit +bc235cdb423a ("bpf: Prevent deadlock from recursive bpf_task_storage_[get|delete]") +first introduced deadlock prevention for fentry/fexit programs attaching +on bpf_task_storage helpers. That commit also employed the logic in map +free path in its v6 version. + +Later bpf_cgrp_storage was first introduced in +c4bcfb38a95e ("bpf: Implement cgroup storage available to non-cgroup-attached bpf progs") +which faces the same issue as bpf_task_storage, instead of its busy +counter, NULL was passed to bpf_local_storage_map_free() which opened +a window to cause deadlock: + + + (acquiring local_storage->lock) + _raw_spin_lock_irqsave+0x3d/0x50 + bpf_local_storage_update+0xd1/0x460 + bpf_cgrp_storage_get+0x109/0x130 + bpf_prog_a4d4a370ba857314_cgrp_ptr+0x139/0x170 + ? __bpf_prog_enter_recur+0x16/0x80 + bpf_trampoline_6442485186+0x43/0xa4 + cgroup_storage_ptr+0x9/0x20 + (holding local_storage->lock) + bpf_selem_unlink_storage_nolock.constprop.0+0x135/0x160 + bpf_selem_unlink_storage+0x6f/0x110 + bpf_local_storage_map_free+0xa2/0x110 + bpf_map_free_deferred+0x5b/0x90 + process_one_work+0x17c/0x390 + worker_thread+0x251/0x360 + kthread+0xd2/0x100 + ret_from_fork+0x34/0x50 + ret_from_fork_asm+0x1a/0x30 + + +Progs: + - A: SEC("fentry/cgroup_storage_ptr") + - cgid (BPF_MAP_TYPE_HASH) + Record the id of the cgroup the current task belonging + to in this hash map, using the address of the cgroup + as the map key. + - cgrpa (BPF_MAP_TYPE_CGRP_STORAGE) + If current task is a kworker, lookup the above hash + map using function parameter @owner as the key to get + its corresponding cgroup id which is then used to get + a trusted pointer to the cgroup through + bpf_cgroup_from_id(). This trusted pointer can then + be passed to bpf_cgrp_storage_get() to finally trigger + the deadlock issue. + - B: SEC("tp_btf/sys_enter") + - cgrpb (BPF_MAP_TYPE_CGRP_STORAGE) + The only purpose of this prog is to fill Prog A's + hash map by calling bpf_cgrp_storage_get() for as + many userspace tasks as possible. + +Steps to reproduce: + - Run A; + - while (true) { Run B; Destroy B; } + +Fix this issue by passing its busy counter to the free procedure so +it can be properly incremented before storage/smap locking. + +Fixes: c4bcfb38a95e ("bpf: Implement cgroup storage available to non-cgroup-attached bpf progs") +Signed-off-by: Abel Wu +Acked-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20241221061018.37717-1-wuyun.abel@bytedance.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/bpf_cgrp_storage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c +index d44fe8dd97329..ee1c7b77096e7 100644 +--- a/kernel/bpf/bpf_cgrp_storage.c ++++ b/kernel/bpf/bpf_cgrp_storage.c +@@ -154,7 +154,7 @@ static struct bpf_map *cgroup_storage_map_alloc(union bpf_attr *attr) + + static void cgroup_storage_map_free(struct bpf_map *map) + { +- bpf_local_storage_map_free(map, &cgroup_cache, NULL); ++ bpf_local_storage_map_free(map, &cgroup_cache, &bpf_cgrp_storage_busy); + } + + /* *gfp_flags* is a hidden argument provided by the verifier */ +-- +2.39.5 + diff --git a/queue-6.6/bpf-fix-wrong-copied_seq-calculation.patch b/queue-6.6/bpf-fix-wrong-copied_seq-calculation.patch new file mode 100644 index 0000000000..cb5106738d --- /dev/null +++ b/queue-6.6/bpf-fix-wrong-copied_seq-calculation.patch @@ -0,0 +1,235 @@ +From 6ed68d1b7972ac3e24a87df0e4061bd972113fff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 18:09:14 +0800 +Subject: bpf: Fix wrong copied_seq calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jiayuan Chen + +[ Upstream commit 36b62df5683c315ba58c950f1a9c771c796c30ec ] + +'sk->copied_seq' was updated in the tcp_eat_skb() function when the action +of a BPF program was SK_REDIRECT. For other actions, like SK_PASS, the +update logic for 'sk->copied_seq' was moved to tcp_bpf_recvmsg_parser() +to ensure the accuracy of the 'fionread' feature. + +It works for a single stream_verdict scenario, as it also modified +sk_data_ready->sk_psock_verdict_data_ready->tcp_read_skb +to remove updating 'sk->copied_seq'. + +However, for programs where both stream_parser and stream_verdict are +active (strparser purpose), tcp_read_sock() was used instead of +tcp_read_skb() (sk_data_ready->strp_data_ready->tcp_read_sock). +tcp_read_sock() now still updates 'sk->copied_seq', leading to duplicate +updates. + +In summary, for strparser + SK_PASS, copied_seq is redundantly calculated +in both tcp_read_sock() and tcp_bpf_recvmsg_parser(). + +The issue causes incorrect copied_seq calculations, which prevent +correct data reads from the recv() interface in user-land. + +We do not want to add new proto_ops to implement a new version of +tcp_read_sock, as this would introduce code complexity [1]. + +We could have added noack and copied_seq to desc, and then called +ops->read_sock. However, unfortunately, other modules didn’t fully +initialize desc to zero. So, for now, we are directly calling +tcp_read_sock_noack() in tcp_bpf.c. + +[1]: https://lore.kernel.org/bpf/20241218053408.437295-1-mrpre@163.com + +Fixes: e5c6de5fa025 ("bpf, sockmap: Incorrectly handling copied_seq") +Suggested-by: Jakub Sitnicki +Signed-off-by: Jiayuan Chen +Signed-off-by: Martin KaFai Lau +Reviewed-by: Jakub Sitnicki +Acked-by: John Fastabend +Link: https://patch.msgid.link/20250122100917.49845-3-mrpre@163.com +Signed-off-by: Sasha Levin +--- + include/linux/skmsg.h | 2 ++ + include/net/tcp.h | 8 ++++++++ + net/core/skmsg.c | 7 +++++++ + net/ipv4/tcp.c | 29 ++++++++++++++++++++++++----- + net/ipv4/tcp_bpf.c | 36 ++++++++++++++++++++++++++++++++++++ + 5 files changed, 77 insertions(+), 5 deletions(-) + +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index 6ccfd9236387c..32bbebf5b71e3 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -87,6 +87,8 @@ struct sk_psock { + struct sk_psock_progs progs; + #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) + struct strparser strp; ++ u32 copied_seq; ++ u32 ingress_bytes; + #endif + struct sk_buff_head ingress_skb; + struct list_head ingress_msg; +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 78c755414fa87..a6def0aab3ed3 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -690,6 +690,9 @@ void tcp_get_info(struct sock *, struct tcp_info *); + /* Read 'sendfile()'-style from a TCP socket */ + int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor); ++int tcp_read_sock_noack(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq); + int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor); + struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off); + void tcp_read_done(struct sock *sk, size_t len); +@@ -2404,6 +2407,11 @@ struct sk_psock; + #ifdef CONFIG_BPF_SYSCALL + int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore); + void tcp_bpf_clone(const struct sock *sk, struct sock *newsk); ++#ifdef CONFIG_BPF_STREAM_PARSER ++struct strparser; ++int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); ++#endif /* CONFIG_BPF_STREAM_PARSER */ + #endif /* CONFIG_BPF_SYSCALL */ + + #ifdef CONFIG_INET +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 902098e221b39..b9b941c487c8a 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -548,6 +548,9 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, + return num_sge; + } + ++#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) ++ psock->ingress_bytes += len; ++#endif + copied = len; + msg->sg.start = 0; + msg->sg.size = copied; +@@ -1143,6 +1146,10 @@ int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock) + if (!ret) + sk_psock_set_state(psock, SK_PSOCK_RX_STRP_ENABLED); + ++ if (sk_is_tcp(sk)) { ++ psock->strp.cb.read_sock = tcp_bpf_strp_read_sock; ++ psock->copied_seq = tcp_sk(sk)->copied_seq; ++ } + return ret; + } + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 5e6615f69f175..7ad82be40f348 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1553,12 +1553,13 @@ EXPORT_SYMBOL(tcp_recv_skb); + * or for 'peeking' the socket using this routine + * (although both would be easy to implement). + */ +-int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, +- sk_read_actor_t recv_actor) ++static int __tcp_read_sock(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq) + { + struct sk_buff *skb; + struct tcp_sock *tp = tcp_sk(sk); +- u32 seq = tp->copied_seq; ++ u32 seq = *copied_seq; + u32 offset; + int copied = 0; + +@@ -1612,9 +1613,12 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + tcp_eat_recv_skb(sk, skb); + if (!desc->count) + break; +- WRITE_ONCE(tp->copied_seq, seq); ++ WRITE_ONCE(*copied_seq, seq); + } +- WRITE_ONCE(tp->copied_seq, seq); ++ WRITE_ONCE(*copied_seq, seq); ++ ++ if (noack) ++ goto out; + + tcp_rcv_space_adjust(sk); + +@@ -1623,10 +1627,25 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, + tcp_recv_skb(sk, seq, &offset); + tcp_cleanup_rbuf(sk, copied); + } ++out: + return copied; + } ++ ++int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor) ++{ ++ return __tcp_read_sock(sk, desc, recv_actor, false, ++ &tcp_sk(sk)->copied_seq); ++} + EXPORT_SYMBOL(tcp_read_sock); + ++int tcp_read_sock_noack(struct sock *sk, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor, bool noack, ++ u32 *copied_seq) ++{ ++ return __tcp_read_sock(sk, desc, recv_actor, noack, copied_seq); ++} ++ + int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { + struct sk_buff *skb; +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index f882054fae5ee..5312237e80409 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -646,6 +646,42 @@ static int tcp_bpf_assert_proto_ops(struct proto *ops) + ops->sendmsg == tcp_sendmsg ? 0 : -ENOTSUPP; + } + ++#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) ++int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor) ++{ ++ struct sock *sk = strp->sk; ++ struct sk_psock *psock; ++ struct tcp_sock *tp; ++ int copied = 0; ++ ++ tp = tcp_sk(sk); ++ rcu_read_lock(); ++ psock = sk_psock(sk); ++ if (WARN_ON_ONCE(!psock)) { ++ desc->error = -EINVAL; ++ goto out; ++ } ++ ++ psock->ingress_bytes = 0; ++ copied = tcp_read_sock_noack(sk, desc, recv_actor, true, ++ &psock->copied_seq); ++ if (copied < 0) ++ goto out; ++ /* recv_actor may redirect skb to another socket (SK_REDIRECT) or ++ * just put skb into ingress queue of current socket (SK_PASS). ++ * For SK_REDIRECT, we need to ack the frame immediately but for ++ * SK_PASS, we want to delay the ack until tcp_bpf_recvmsg_parser(). ++ */ ++ tp->copied_seq = psock->copied_seq - psock->ingress_bytes; ++ tcp_rcv_space_adjust(sk); ++ __tcp_cleanup_rbuf(sk, copied - psock->ingress_bytes); ++out: ++ rcu_read_unlock(); ++ return copied; ++} ++#endif /* CONFIG_BPF_STREAM_PARSER */ ++ + int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) + { + int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4; +-- +2.39.5 + diff --git a/queue-6.6/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch b/queue-6.6/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch new file mode 100644 index 0000000000..8ec8107125 --- /dev/null +++ b/queue-6.6/bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch @@ -0,0 +1,119 @@ +From f5f0afe9e33290826824330918e017a1e1c89001 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 23:22:35 -0800 +Subject: bpf: skip non exist keys in generic_map_lookup_batch + +From: Yan Zhai + +[ Upstream commit 5644c6b50ffee0a56c1e01430a8c88e34decb120 ] + +The generic_map_lookup_batch currently returns EINTR if it fails with +ENOENT and retries several times on bpf_map_copy_value. The next batch +would start from the same location, presuming it's a transient issue. +This is incorrect if a map can actually have "holes", i.e. +"get_next_key" can return a key that does not point to a valid value. At +least the array of maps type may contain such holes legitly. Right now +these holes show up, generic batch lookup cannot proceed any more. It +will always fail with EINTR errors. + +Rather, do not retry in generic_map_lookup_batch. If it finds a non +existing element, skip to the next key. This simple solution comes with +a price that transient errors may not be recovered, and the iteration +might cycle back to the first key under parallel deletion. For example, +Hou Tao pointed out a following scenario: + +For LPM trie map: +(1) ->map_get_next_key(map, prev_key, key) returns a valid key + +(2) bpf_map_copy_value() return -ENOMENT +It means the key must be deleted concurrently. + +(3) goto next_key +It swaps the prev_key and key + +(4) ->map_get_next_key(map, prev_key, key) again +prev_key points to a non-existing key, for LPM trie it will treat just +like prev_key=NULL case, the returned key will be duplicated. + +With the retry logic, the iteration can continue to the key next to the +deleted one. But if we directly skip to the next key, the iteration loop +would restart from the first key for the lpm_trie type. + +However, not all races may be recovered. For example, if current key is +deleted after instead of before bpf_map_copy_value, or if the prev_key +also gets deleted, then the loop will still restart from the first key +for lpm_tire anyway. For generic lookup it might be better to stay +simple, i.e. just skip to the next key. To guarantee that the output +keys are not duplicated, it is better to implement map type specific +batch operations, which can properly lock the trie and synchronize with +concurrent mutators. + +Fixes: cb4d03ab499d ("bpf: Add generic support for lookup batch op") +Closes: https://lore.kernel.org/bpf/Z6JXtA1M5jAZx8xD@debian.debian/ +Signed-off-by: Yan Zhai +Acked-by: Hou Tao +Link: https://lore.kernel.org/r/85618439eea75930630685c467ccefeac0942e2b.1739171594.git.yan@cloudflare.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 9f791b6b09edc..f089a61630111 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -1807,8 +1807,6 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file, + return err; + } + +-#define MAP_LOOKUP_RETRIES 3 +- + int generic_map_lookup_batch(struct bpf_map *map, + const union bpf_attr *attr, + union bpf_attr __user *uattr) +@@ -1818,8 +1816,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + void __user *values = u64_to_user_ptr(attr->batch.values); + void __user *keys = u64_to_user_ptr(attr->batch.keys); + void *buf, *buf_prevkey, *prev_key, *key, *value; +- int err, retry = MAP_LOOKUP_RETRIES; + u32 value_size, cp, max_count; ++ int err; + + if (attr->batch.elem_flags & ~BPF_F_LOCK) + return -EINVAL; +@@ -1865,14 +1863,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + err = bpf_map_copy_value(map, key, value, + attr->batch.elem_flags); + +- if (err == -ENOENT) { +- if (retry) { +- retry--; +- continue; +- } +- err = -EINTR; +- break; +- } ++ if (err == -ENOENT) ++ goto next_key; + + if (err) + goto free_buf; +@@ -1887,12 +1879,12 @@ int generic_map_lookup_batch(struct bpf_map *map, + goto free_buf; + } + ++ cp++; ++next_key: + if (!prev_key) + prev_key = buf_prevkey; + + swap(prev_key, key); +- retry = MAP_LOOKUP_RETRIES; +- cp++; + cond_resched(); + } + +-- +2.39.5 + diff --git a/queue-6.6/bpf-test_run-fix-use-after-free-issue-in-eth_skb_pkt.patch b/queue-6.6/bpf-test_run-fix-use-after-free-issue-in-eth_skb_pkt.patch new file mode 100644 index 0000000000..36bafcd20d --- /dev/null +++ b/queue-6.6/bpf-test_run-fix-use-after-free-issue-in-eth_skb_pkt.patch @@ -0,0 +1,92 @@ +From 2d3c9628945d3ca74a456fcd9d0c22e2694d035e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 00:06:42 +0900 +Subject: bpf, test_run: Fix use-after-free issue in eth_skb_pkt_type() + +From: Shigeru Yoshida + +[ Upstream commit 6b3d638ca897e099fa99bd6d02189d3176f80a47 ] + +KMSAN reported a use-after-free issue in eth_skb_pkt_type()[1]. The +cause of the issue was that eth_skb_pkt_type() accessed skb's data +that didn't contain an Ethernet header. This occurs when +bpf_prog_test_run_xdp() passes an invalid value as the user_data +argument to bpf_test_init(). + +Fix this by returning an error when user_data is less than ETH_HLEN in +bpf_test_init(). Additionally, remove the check for "if (user_size > +size)" as it is unnecessary. + +[1] +BUG: KMSAN: use-after-free in eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] +BUG: KMSAN: use-after-free in eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 + eth_skb_pkt_type include/linux/etherdevice.h:627 [inline] + eth_type_trans+0x4ee/0x980 net/ethernet/eth.c:165 + __xdp_build_skb_from_frame+0x5a8/0xa50 net/core/xdp.c:635 + xdp_recv_frames net/bpf/test_run.c:272 [inline] + xdp_test_run_batch net/bpf/test_run.c:361 [inline] + bpf_test_run_xdp_live+0x2954/0x3330 net/bpf/test_run.c:390 + bpf_prog_test_run_xdp+0x148e/0x1b10 net/bpf/test_run.c:1318 + bpf_prog_test_run+0x5b7/0xa30 kernel/bpf/syscall.c:4371 + __sys_bpf+0x6a6/0xe20 kernel/bpf/syscall.c:5777 + __do_sys_bpf kernel/bpf/syscall.c:5866 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5864 [inline] + __x64_sys_bpf+0xa4/0xf0 kernel/bpf/syscall.c:5864 + x64_sys_call+0x2ea0/0x3d90 arch/x86/include/generated/asm/syscalls_64.h:322 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xd9/0x1d0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Uninit was created at: + free_pages_prepare mm/page_alloc.c:1056 [inline] + free_unref_page+0x156/0x1320 mm/page_alloc.c:2657 + __free_pages+0xa3/0x1b0 mm/page_alloc.c:4838 + bpf_ringbuf_free kernel/bpf/ringbuf.c:226 [inline] + ringbuf_map_free+0xff/0x1e0 kernel/bpf/ringbuf.c:235 + bpf_map_free kernel/bpf/syscall.c:838 [inline] + bpf_map_free_deferred+0x17c/0x310 kernel/bpf/syscall.c:862 + process_one_work kernel/workqueue.c:3229 [inline] + process_scheduled_works+0xa2b/0x1b60 kernel/workqueue.c:3310 + worker_thread+0xedf/0x1550 kernel/workqueue.c:3391 + kthread+0x535/0x6b0 kernel/kthread.c:389 + ret_from_fork+0x6e/0x90 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +CPU: 1 UID: 0 PID: 17276 Comm: syz.1.16450 Not tainted 6.12.0-05490-g9bb88c659673 #8 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 + +Fixes: be3d72a2896c ("bpf: move user_size out of bpf_test_init") +Reported-by: syzkaller +Suggested-by: Martin KaFai Lau +Signed-off-by: Shigeru Yoshida +Signed-off-by: Martin KaFai Lau +Acked-by: Stanislav Fomichev +Acked-by: Daniel Borkmann +Link: https://patch.msgid.link/20250121150643.671650-1-syoshida@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 905de361f8623..73fb9db55798c 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -630,12 +630,9 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + void *data; + +- if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom) ++ if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) + return ERR_PTR(-EINVAL); + +- if (user_size > size) +- return ERR_PTR(-EMSGSIZE); +- + size = SKB_DATA_ALIGN(size); + data = kzalloc(size + headroom + tailroom, GFP_USER); + if (!data) +-- +2.39.5 + diff --git a/queue-6.6/bpf-unify-vm_write-vs-vm_maywrite-use-in-bpf-map-mma.patch b/queue-6.6/bpf-unify-vm_write-vs-vm_maywrite-use-in-bpf-map-mma.patch new file mode 100644 index 0000000000..b0486cd4b4 --- /dev/null +++ b/queue-6.6/bpf-unify-vm_write-vs-vm_maywrite-use-in-bpf-map-mma.patch @@ -0,0 +1,112 @@ +From 6abd2942dd466a7e7a22f6f2da19dc5ba7cb37a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 17:22:45 -0800 +Subject: bpf: unify VM_WRITE vs VM_MAYWRITE use in BPF map mmaping logic + +From: Andrii Nakryiko + +[ Upstream commit 98671a0fd1f14e4a518ee06b19037c20014900eb ] + +For all BPF maps we ensure that VM_MAYWRITE is cleared when +memory-mapping BPF map contents as initially read-only VMA. This is +because in some cases BPF verifier relies on the underlying data to not +be modified afterwards by user space, so once something is mapped +read-only, it shouldn't be re-mmap'ed as read-write. + +As such, it's not necessary to check VM_MAYWRITE in bpf_map_mmap() and +map->ops->map_mmap() callbacks: VM_WRITE should be consistently set for +read-write mappings, and if VM_WRITE is not set, there is no way for +user space to upgrade read-only mapping to read-write one. + +This patch cleans up this VM_WRITE vs VM_MAYWRITE handling within +bpf_map_mmap(), which is an entry point for any BPF map mmap()-ing +logic. We also drop unnecessary sanitization of VM_MAYWRITE in BPF +ringbuf's map_mmap() callback implementation, as it is already performed +by common code in bpf_map_mmap(). + +Note, though, that in bpf_map_mmap_{open,close}() callbacks we can't +drop VM_MAYWRITE use, because it's possible (and is outside of +subsystem's control) to have initially read-write memory mapping, which +is subsequently dropped to read-only by user space through mprotect(). +In such case, from BPF verifier POV it's read-write data throughout the +lifetime of BPF map, and is counted as "active writer". + +But its VMAs will start out as VM_WRITE|VM_MAYWRITE, then mprotect() can +change it to just VM_MAYWRITE (and no VM_WRITE), so when its finally +munmap()'ed and bpf_map_mmap_close() is called, vm_flags will be just +VM_MAYWRITE, but we still need to decrement active writer count with +bpf_map_write_active_dec() as it's still considered to be a read-write +mapping by the rest of BPF subsystem. + +Similar reasoning applies to bpf_map_mmap_open(), which is called +whenever mmap(), munmap(), and/or mprotect() forces mm subsystem to +split original VMA into multiple discontiguous VMAs. + +Memory-mapping handling is a bit tricky, yes. + +Cc: Jann Horn +Cc: Suren Baghdasaryan +Cc: Shakeel Butt +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20250129012246.1515826-1-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Stable-dep-of: bc27c52eea18 ("bpf: avoid holding freeze_mutex during mmap operation") +Signed-off-by: Sasha Levin +--- + kernel/bpf/ringbuf.c | 4 ---- + kernel/bpf/syscall.c | 10 ++++++++-- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c +index 246559c3e93d0..528f4d6342262 100644 +--- a/kernel/bpf/ringbuf.c ++++ b/kernel/bpf/ringbuf.c +@@ -268,8 +268,6 @@ static int ringbuf_map_mmap_kern(struct bpf_map *map, struct vm_area_struct *vma + /* allow writable mapping for the consumer_pos only */ + if (vma->vm_pgoff != 0 || vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EPERM; +- } else { +- vm_flags_clear(vma, VM_MAYWRITE); + } + /* remap_vmalloc_range() checks size and offset constraints */ + return remap_vmalloc_range(vma, rb_map->rb, +@@ -289,8 +287,6 @@ static int ringbuf_map_mmap_user(struct bpf_map *map, struct vm_area_struct *vma + * position, and the ring buffer data itself. + */ + return -EPERM; +- } else { +- vm_flags_clear(vma, VM_MAYWRITE); + } + /* remap_vmalloc_range() checks size and offset constraints */ + return remap_vmalloc_range(vma, rb_map->rb, vma->vm_pgoff + RINGBUF_PGOFF); +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index ba38c08a9a059..98d7558e2f2be 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -912,15 +912,21 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) + vma->vm_ops = &bpf_map_default_vmops; + vma->vm_private_data = map; + vm_flags_clear(vma, VM_MAYEXEC); ++ /* If mapping is read-only, then disallow potentially re-mapping with ++ * PROT_WRITE by dropping VM_MAYWRITE flag. This VM_MAYWRITE clearing ++ * means that as far as BPF map's memory-mapped VMAs are concerned, ++ * VM_WRITE and VM_MAYWRITE and equivalent, if one of them is set, ++ * both should be set, so we can forget about VM_MAYWRITE and always ++ * check just VM_WRITE ++ */ + if (!(vma->vm_flags & VM_WRITE)) +- /* disallow re-mapping with PROT_WRITE */ + vm_flags_clear(vma, VM_MAYWRITE); + + err = map->ops->map_mmap(map, vma); + if (err) + goto out; + +- if (vma->vm_flags & VM_MAYWRITE) ++ if (vma->vm_flags & VM_WRITE) + bpf_map_write_active_inc(map); + out: + mutex_unlock(&map->freeze_mutex); +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-avoid-rounding-up-to-one-jiffy.patch b/queue-6.6/drm-msm-avoid-rounding-up-to-one-jiffy.patch new file mode 100644 index 0000000000..d758ae0445 --- /dev/null +++ b/queue-6.6/drm-msm-avoid-rounding-up-to-one-jiffy.patch @@ -0,0 +1,48 @@ +From 3a197c505b29dc93529d7249ac6f661527ade17c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 07:48:41 -0800 +Subject: drm/msm: Avoid rounding up to one jiffy + +From: Rob Clark + +[ Upstream commit 669c285620231786fffe9d87ab432e08a6ed922b ] + +If userspace is trying to achieve a timeout of zero, let 'em have it. +Only round up if the timeout is greater than zero. + +Fixes: 4969bccd5f4e ("drm/msm: Avoid rounding down to zero jiffies") +Signed-off-by: Rob Clark +Reviewed-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/632264/ +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_drv.h | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h +index 48e1a8c6942c9..223bf904235a8 100644 +--- a/drivers/gpu/drm/msm/msm_drv.h ++++ b/drivers/gpu/drm/msm/msm_drv.h +@@ -533,15 +533,12 @@ static inline int align_pitch(int width, int bpp) + static inline unsigned long timeout_to_jiffies(const ktime_t *timeout) + { + ktime_t now = ktime_get(); +- s64 remaining_jiffies; + +- if (ktime_compare(*timeout, now) < 0) { +- remaining_jiffies = 0; +- } else { +- ktime_t rem = ktime_sub(*timeout, now); +- remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ); +- } ++ if (ktime_compare(*timeout, now) <= 0) ++ return 0; + ++ ktime_t rem = ktime_sub(*timeout, now); ++ s64 remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ); + return clamp(remaining_jiffies, 1LL, (s64)INT_MAX); + } + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dpu-don-t-leak-bits_per_component-into-rando.patch b/queue-6.6/drm-msm-dpu-don-t-leak-bits_per_component-into-rando.patch new file mode 100644 index 0000000000..fe1b813618 --- /dev/null +++ b/queue-6.6/drm-msm-dpu-don-t-leak-bits_per_component-into-rando.patch @@ -0,0 +1,68 @@ +From 8a0a45ce4f024478195c1d2e93fca2e785189652 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Feb 2025 00:19:32 +0100 +Subject: drm/msm/dpu: Don't leak bits_per_component into random DSC_ENC fields + +From: Marijn Suijten + +[ Upstream commit 144429831f447223253a0e4376489f84ff37d1a7 ] + +What used to be the input_10_bits boolean - feeding into the lowest +bit of DSC_ENC - on MSM downstream turned into an accidental OR with +the full bits_per_component number when it was ported to the upstream +kernel. + +On typical bpc=8 setups we don't notice this because line_buf_depth is +always an odd value (it contains bpc+1) and will also set the 4th bit +after left-shifting by 3 (hence this |= bits_per_component is a no-op). + +Now that guards are being removed to allow more bits_per_component +values besides 8 (possible since commit 49fd30a7153b ("drm/msm/dsi: use +DRM DSC helpers for DSC setup")), a bpc of 10 will instead clash with +the 5th bit which is convert_rgb. This is "fortunately" also always set +to true by MSM's dsi_populate_dsc_params() already, but once a bpc of 12 +starts being used it'll write into simple_422 which is normally false. + +To solve all these overlaps, simply replicate downstream code and only +set this lowest bit if bits_per_component is equal to 10. It is unclear +why DSC requires this only for bpc=10 but not bpc=12, and also notice +that this lowest bit wasn't set previously despite having a panel and +patch on the list using it without any mentioned issues. + +Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC") +Signed-off-by: Marijn Suijten +Reviewed-by: Abhinav Kumar +Reviewed-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/636311/ +Link: https://lore.kernel.org/r/20250211-dsc-10-bit-v1-1-1c85a9430d9a@somainline.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +index 509dbaa51d878..12e79a71ae4cd 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +@@ -50,6 +50,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + u32 slice_last_group_size; + u32 det_thresh_flatness; + bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); ++ bool input_10_bits = dsc->bits_per_component == 10; + + DPU_REG_WRITE(c, DSC_COMMON_MODE, mode); + +@@ -66,7 +67,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + data |= (dsc->line_buf_depth << 3); + data |= (dsc->simple_422 << 2); + data |= (dsc->convert_rgb << 1); +- data |= dsc->bits_per_component; ++ data |= input_10_bits; + + DPU_REG_WRITE(c, DSC_ENC, data); + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dpu-rename-dpu_hw_setup_vsync_source-functio.patch b/queue-6.6/drm-msm-dpu-rename-dpu_hw_setup_vsync_source-functio.patch new file mode 100644 index 0000000000..f09268d54d --- /dev/null +++ b/queue-6.6/drm-msm-dpu-rename-dpu_hw_setup_vsync_source-functio.patch @@ -0,0 +1,73 @@ +From 0725c195726daf14d2b53c3afe904ff4a8f802f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jun 2024 20:05:11 +0300 +Subject: drm/msm/dpu: rename dpu_hw_setup_vsync_source functions + +From: Dmitry Baryshkov + +[ Upstream commit 8ba16ca8cc96dfe2e2f09146fd386acc3390931c ] + +Rename dpu_hw_setup_vsync_source functions to make the names match the +implementation: on DPU 5.x the TOP only contains timer setup, while 3.x +and 4.x used MDP_VSYNC_SEL register to select TE source. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/598745/ +Link: https://lore.kernel.org/r/20240613-dpu-handle-te-signal-v2-8-67a0116b5366@linaro.org +Stable-dep-of: 2f69e5458447 ("drm/msm/dpu: skip watchdog timer programming through TOP on >= SM8450") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +index cff48763ce25e..fb0f5df70421f 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +@@ -126,8 +126,8 @@ static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp, + status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3; + } + +-static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp, +- struct dpu_vsync_source_cfg *cfg) ++static void dpu_hw_setup_wd_timer(struct dpu_hw_mdp *mdp, ++ struct dpu_vsync_source_cfg *cfg) + { + struct dpu_hw_blk_reg_map *c; + u32 reg, wd_load_value, wd_ctl, wd_ctl2; +@@ -182,8 +182,8 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp, + } + } + +-static void dpu_hw_setup_vsync_source_and_vsync_sel(struct dpu_hw_mdp *mdp, +- struct dpu_vsync_source_cfg *cfg) ++static void dpu_hw_setup_vsync_sel(struct dpu_hw_mdp *mdp, ++ struct dpu_vsync_source_cfg *cfg) + { + struct dpu_hw_blk_reg_map *c; + u32 reg, i; +@@ -206,7 +206,7 @@ static void dpu_hw_setup_vsync_source_and_vsync_sel(struct dpu_hw_mdp *mdp, + } + DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg); + +- dpu_hw_setup_vsync_source(mdp, cfg); ++ dpu_hw_setup_wd_timer(mdp, cfg); + } + + static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp, +@@ -258,9 +258,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, + ops->get_danger_status = dpu_hw_get_danger_status; + + if (cap & BIT(DPU_MDP_VSYNC_SEL)) +- ops->setup_vsync_source = dpu_hw_setup_vsync_source_and_vsync_sel; ++ ops->setup_vsync_source = dpu_hw_setup_vsync_sel; + else +- ops->setup_vsync_source = dpu_hw_setup_vsync_source; ++ ops->setup_vsync_source = dpu_hw_setup_wd_timer; + + ops->get_safe_status = dpu_hw_get_safe_status; + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dpu-skip-watchdog-timer-programming-through-.patch b/queue-6.6/drm-msm-dpu-skip-watchdog-timer-programming-through-.patch new file mode 100644 index 0000000000..31e652d492 --- /dev/null +++ b/queue-6.6/drm-msm-dpu-skip-watchdog-timer-programming-through-.patch @@ -0,0 +1,41 @@ +From 5bc18192340b893d56ac95adbaa40c1b27c68616 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Dec 2024 00:14:17 +0200 +Subject: drm/msm/dpu: skip watchdog timer programming through TOP on >= SM8450 + +From: Dmitry Baryshkov + +[ Upstream commit 2f69e54584475ac85ea0e3407c9198ac7c6ea8ad ] + +The SM8450 and later chips have DPU_MDP_PERIPH_0_REMOVED feature bit +set, which means that those platforms have dropped some of the +registers, including the WD TIMER-related ones. Stop providing the +callback to program WD timer on those platforms. + +Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/628874/ +Link: https://lore.kernel.org/r/20241214-dpu-drop-features-v1-1-988f0662cb7e@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +index fb0f5df70421f..597aa05efd843 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +@@ -259,7 +259,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, + + if (cap & BIT(DPU_MDP_VSYNC_SEL)) + ops->setup_vsync_source = dpu_hw_setup_vsync_sel; +- else ++ else if (!(cap & BIT(DPU_MDP_PERIPH_0_REMOVED))) + ops->setup_vsync_source = dpu_hw_setup_wd_timer; + + ops->get_safe_status = dpu_hw_get_safe_status; +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-drop-msm_read-writel.patch b/queue-6.6/drm-msm-drop-msm_read-writel.patch new file mode 100644 index 0000000000..3d810df526 --- /dev/null +++ b/queue-6.6/drm-msm-drop-msm_read-writel.patch @@ -0,0 +1,379 @@ +From 7496ca7e98a0bea483beb993af836bf76c17c826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Apr 2024 23:52:52 +0200 +Subject: drm/msm: Drop msm_read/writel + +From: Konrad Dybcio + +[ Upstream commit 0efadfb0050e1b65c14650406d8c7e5126c08b69 ] + +Totally useless. + +Signed-off-by: Konrad Dybcio +Reviewed-by: Andrew Halaney +Patchwork: https://patchwork.freedesktop.org/patch/588804/ +Link: https://lore.kernel.org/r/20240410-topic-msm_rw-v1-1-e1fede9ffaba@linaro.org +Signed-off-by: Dmitry Baryshkov +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 2 +- + drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 12 ++++++------ + drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 4 ++-- + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 4 ++-- + drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 4 ++-- + drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 4 ++-- + drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +++++----- + drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 8 ++++---- + drivers/gpu/drm/msm/hdmi/hdmi.h | 10 +++++----- + drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 6 +++--- + drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c | 4 ++-- + drivers/gpu/drm/msm/msm_drv.h | 7 ++----- + drivers/gpu/drm/msm/msm_gpu.h | 12 ++++++------ + 13 files changed, 42 insertions(+), 45 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index 9009442b543dd..ac6aace4439d5 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -501,7 +501,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) + + static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value) + { +- msm_writel(value, ptr + (offset << 2)); ++ writel(value, ptr + (offset << 2)); + } + + static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +index 236f81a43caa6..3de610eff6480 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +@@ -100,12 +100,12 @@ struct a6xx_gmu { + + static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) + { +- return msm_readl(gmu->mmio + (offset << 2)); ++ return readl(gmu->mmio + (offset << 2)); + } + + static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value) + { +- msm_writel(value, gmu->mmio + (offset << 2)); ++ writel(value, gmu->mmio + (offset << 2)); + } + + static inline void +@@ -128,8 +128,8 @@ static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi) + { + u64 val; + +- val = (u64) msm_readl(gmu->mmio + (lo << 2)); +- val |= ((u64) msm_readl(gmu->mmio + (hi << 2)) << 32); ++ val = (u64) readl(gmu->mmio + (lo << 2)); ++ val |= ((u64) readl(gmu->mmio + (hi << 2)) << 32); + + return val; + } +@@ -140,12 +140,12 @@ static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi) + + static inline u32 gmu_read_rscc(struct a6xx_gmu *gmu, u32 offset) + { +- return msm_readl(gmu->rscc + (offset << 2)); ++ return readl(gmu->rscc + (offset << 2)); + } + + static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value) + { +- msm_writel(value, gmu->rscc + (offset << 2)); ++ writel(value, gmu->rscc + (offset << 2)); + } + + #define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \ +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +index 34822b0807593..8917032b75156 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +@@ -69,12 +69,12 @@ static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u3 + + static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg) + { +- return msm_readl(a6xx_gpu->llc_mmio + (reg << 2)); ++ return readl(a6xx_gpu->llc_mmio + (reg << 2)); + } + + static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value) + { +- msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2)); ++ writel(value, a6xx_gpu->llc_mmio + (reg << 2)); + } + + #define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \ +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +index 4e5d650578c60..ee2a095cec83b 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +@@ -181,10 +181,10 @@ static int debugbus_read(struct msm_gpu *gpu, u32 block, u32 offset, + } + + #define cxdbg_write(ptr, offset, val) \ +- msm_writel((val), (ptr) + ((offset) << 2)) ++ writel((val), (ptr) + ((offset) << 2)) + + #define cxdbg_read(ptr, offset) \ +- msm_readl((ptr) + ((offset) << 2)) ++ readl((ptr) + ((offset) << 2)) + + /* read a value from the CX debug bus */ + static int cx_debugbus_read(void __iomem *cxdbg, u32 block, u32 offset, +diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +index 01179e764a294..94b1ba92785fe 100644 +--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h ++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +@@ -44,12 +44,12 @@ struct mdp4_kms { + + static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data) + { +- msm_writel(data, mdp4_kms->mmio + reg); ++ writel(data, mdp4_kms->mmio + reg); + } + + static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg) + { +- return msm_readl(mdp4_kms->mmio + reg); ++ return readl(mdp4_kms->mmio + reg); + } + + static inline uint32_t pipe2flush(enum mdp4_pipe pipe) +diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +index 29bf11f086011..a61fad926d65e 100644 +--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h ++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +@@ -172,13 +172,13 @@ struct mdp5_encoder { + static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) + { + WARN_ON(mdp5_kms->enable_count <= 0); +- msm_writel(data, mdp5_kms->mmio + reg); ++ writel(data, mdp5_kms->mmio + reg); + } + + static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg) + { + WARN_ON(mdp5_kms->enable_count <= 0); +- return msm_readl(mdp5_kms->mmio + reg); ++ return readl(mdp5_kms->mmio + reg); + } + + static inline const char *stage2name(enum mdp_mixer_stage_id stage) +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index f920329fe2e09..4c3c04d65faa6 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -55,7 +55,7 @@ static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) + * scratch register which we never touch) + */ + +- ver = msm_readl(base + REG_DSI_VERSION); ++ ver = readl(base + REG_DSI_VERSION); + if (ver) { + /* older dsi host, there is no register shift */ + ver = FIELD(ver, DSI_VERSION_MAJOR); +@@ -73,12 +73,12 @@ static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) + * registers are shifted down, read DSI_VERSION again with + * the shifted offset + */ +- ver = msm_readl(base + DSI_6G_REG_SHIFT + REG_DSI_VERSION); ++ ver = readl(base + DSI_6G_REG_SHIFT + REG_DSI_VERSION); + ver = FIELD(ver, DSI_VERSION_MAJOR); + if (ver == MSM_DSI_VER_MAJOR_6G) { + /* 6G version */ + *major = ver; +- *minor = msm_readl(base + REG_DSI_6G_HW_VERSION); ++ *minor = readl(base + REG_DSI_6G_HW_VERSION); + return 0; + } else { + return -EINVAL; +@@ -196,11 +196,11 @@ static u32 dsi_get_bpp(const enum mipi_dsi_pixel_format fmt) + + static inline u32 dsi_read(struct msm_dsi_host *msm_host, u32 reg) + { +- return msm_readl(msm_host->ctrl_base + reg); ++ return readl(msm_host->ctrl_base + reg); + } + static inline void dsi_write(struct msm_dsi_host *msm_host, u32 reg, u32 data) + { +- msm_writel(data, msm_host->ctrl_base + reg); ++ writel(data, msm_host->ctrl_base + reg); + } + + static const struct msm_dsi_cfg_handler *dsi_get_config( +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +index 8b640d1747851..1ff74689eefa0 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +@@ -12,10 +12,10 @@ + + #include "dsi.h" + +-#define dsi_phy_read(offset) msm_readl((offset)) +-#define dsi_phy_write(offset, data) msm_writel((data), (offset)) +-#define dsi_phy_write_udelay(offset, data, delay_us) { msm_writel((data), (offset)); udelay(delay_us); } +-#define dsi_phy_write_ndelay(offset, data, delay_ns) { msm_writel((data), (offset)); ndelay(delay_ns); } ++#define dsi_phy_read(offset) readl((offset)) ++#define dsi_phy_write(offset, data) writel((data), (offset)) ++#define dsi_phy_write_udelay(offset, data, delay_us) { writel((data), (offset)); udelay(delay_us); } ++#define dsi_phy_write_ndelay(offset, data, delay_ns) { writel((data), (offset)); ndelay(delay_ns); } + + struct msm_dsi_phy_ops { + int (*pll_init)(struct msm_dsi_phy *phy); +diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h +index e8dbee50637fa..0a21f9e691948 100644 +--- a/drivers/gpu/drm/msm/hdmi/hdmi.h ++++ b/drivers/gpu/drm/msm/hdmi/hdmi.h +@@ -115,17 +115,17 @@ void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on); + + static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data) + { +- msm_writel(data, hdmi->mmio + reg); ++ writel(data, hdmi->mmio + reg); + } + + static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) + { +- return msm_readl(hdmi->mmio + reg); ++ return readl(hdmi->mmio + reg); + } + + static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg) + { +- return msm_readl(hdmi->qfprom_mmio + reg); ++ return readl(hdmi->qfprom_mmio + reg); + } + + /* +@@ -166,12 +166,12 @@ struct hdmi_phy { + + static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data) + { +- msm_writel(data, phy->mmio + reg); ++ writel(data, phy->mmio + reg); + } + + static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg) + { +- return msm_readl(phy->mmio + reg); ++ return readl(phy->mmio + reg); + } + + int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy); +diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +index 4dd0554166204..8c8d80b59573a 100644 +--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c ++++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +@@ -86,18 +86,18 @@ static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll) + static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset, + u32 data) + { +- msm_writel(data, pll->mmio_qserdes_com + offset); ++ writel(data, pll->mmio_qserdes_com + offset); + } + + static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset) + { +- return msm_readl(pll->mmio_qserdes_com + offset); ++ return readl(pll->mmio_qserdes_com + offset); + } + + static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel, + int offset, int data) + { +- msm_writel(data, pll->mmio_qserdes_tx[channel] + offset); ++ writel(data, pll->mmio_qserdes_tx[channel] + offset); + } + + static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk, +diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c +index cb35a297afbd1..83c8781fcc3f6 100644 +--- a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c ++++ b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c +@@ -236,12 +236,12 @@ static const struct pll_rate freqtbl[] = { + + static inline void pll_write(struct hdmi_pll_8960 *pll, u32 reg, u32 data) + { +- msm_writel(data, pll->mmio + reg); ++ writel(data, pll->mmio + reg); + } + + static inline u32 pll_read(struct hdmi_pll_8960 *pll, u32 reg) + { +- return msm_readl(pll->mmio + reg); ++ return readl(pll->mmio + reg); + } + + static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8960 *pll) +diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h +index 223bf904235a8..4a33d39a1c3d5 100644 +--- a/drivers/gpu/drm/msm/msm_drv.h ++++ b/drivers/gpu/drm/msm/msm_drv.h +@@ -476,15 +476,12 @@ void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name); + + struct icc_path *msm_icc_get(struct device *dev, const char *name); + +-#define msm_writel(data, addr) writel((data), (addr)) +-#define msm_readl(addr) readl((addr)) +- + static inline void msm_rmw(void __iomem *addr, u32 mask, u32 or) + { +- u32 val = msm_readl(addr); ++ u32 val = readl(addr); + + val &= ~mask; +- msm_writel(val | or, addr); ++ writel(val | or, addr); + } + + /** +diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h +index 4252e3839fbc8..1fdf6ef63f179 100644 +--- a/drivers/gpu/drm/msm/msm_gpu.h ++++ b/drivers/gpu/drm/msm/msm_gpu.h +@@ -555,12 +555,12 @@ struct msm_gpu_state { + + static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data) + { +- msm_writel(data, gpu->mmio + (reg << 2)); ++ writel(data, gpu->mmio + (reg << 2)); + } + + static inline u32 gpu_read(struct msm_gpu *gpu, u32 reg) + { +- return msm_readl(gpu->mmio + (reg << 2)); ++ return readl(gpu->mmio + (reg << 2)); + } + + static inline void gpu_rmw(struct msm_gpu *gpu, u32 reg, u32 mask, u32 or) +@@ -586,8 +586,8 @@ static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg) + * when the lo is read, so make sure to read the lo first to trigger + * that + */ +- val = (u64) msm_readl(gpu->mmio + (reg << 2)); +- val |= ((u64) msm_readl(gpu->mmio + ((reg + 1) << 2)) << 32); ++ val = (u64) readl(gpu->mmio + (reg << 2)); ++ val |= ((u64) readl(gpu->mmio + ((reg + 1) << 2)) << 32); + + return val; + } +@@ -595,8 +595,8 @@ static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg) + static inline void gpu_write64(struct msm_gpu *gpu, u32 reg, u64 val) + { + /* Why not a writeq here? Read the screed above */ +- msm_writel(lower_32_bits(val), gpu->mmio + (reg << 2)); +- msm_writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2)); ++ writel(lower_32_bits(val), gpu->mmio + (reg << 2)); ++ writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2)); + } + + int msm_gpu_pm_suspend(struct msm_gpu *gpu); +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dsi-phy-do-not-overwite-phy_cmn_clk_cfg1-whe.patch b/queue-6.6/drm-msm-dsi-phy-do-not-overwite-phy_cmn_clk_cfg1-whe.patch new file mode 100644 index 0000000000..25f0874dba --- /dev/null +++ b/queue-6.6/drm-msm-dsi-phy-do-not-overwite-phy_cmn_clk_cfg1-whe.patch @@ -0,0 +1,72 @@ +From a471ddc170c31f06a19092fcd2c478e176c4d04c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 16:08:43 +0100 +Subject: drm/msm/dsi/phy: Do not overwite PHY_CMN_CLK_CFG1 when choosing + bitclk source + +From: Krzysztof Kozlowski + +[ Upstream commit 73f69c6be2a9f22c31c775ec03c6c286bfe12cfa ] + +PHY_CMN_CLK_CFG1 register has four fields being used in the driver: DSI +clock divider, source of bitclk and two for enabling the DSI PHY PLL +clocks. + +dsi_7nm_set_usecase() sets only the source of bitclk, so should leave +all other bits untouched. Use newly introduced +dsi_pll_cmn_clk_cfg1_update() to update respective bits without +overwriting the rest. + +While shuffling the code, define and use PHY_CMN_CLK_CFG1 bitfields to +make the code more readable and obvious. + +Fixes: 1ef7c99d145c ("drm/msm/dsi: add support for 7nm DSI PHY/PLL") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/637380/ +Link: https://lore.kernel.org/r/20250214-drm-msm-phy-pll-cfg-reg-v3-3-0943b850722c@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 4 ++-- + drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +index 991bf10a64248..ad4b3b5cc4944 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +@@ -617,7 +617,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) + static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) + { + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); +- void __iomem *base = phy->base; + u32 data = 0x0; /* internal PLL */ + + DBG("DSI PLL%d", pll_7nm->phy->id); +@@ -636,7 +635,8 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) + } + + /* set PLL src */ +- writel(data << 2, base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ dsi_pll_cmn_clk_cfg1_update(pll_7nm, DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL__MASK, ++ DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL(data)); + + return 0; + } +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +index cfaf78c028b13..35f7f40e405b7 100644 +--- a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +@@ -16,6 +16,7 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> + + + ++ + + + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg0-updated-fro.patch b/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg0-updated-fro.patch new file mode 100644 index 0000000000..d73852f5be --- /dev/null +++ b/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg0-updated-fro.patch @@ -0,0 +1,87 @@ +From 0f62618f50d551a0f3753233604158540491fa19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 16:08:41 +0100 +Subject: drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side + +From: Krzysztof Kozlowski + +[ Upstream commit 588257897058a0b1aa47912db4fe93c6ff5e3887 ] + +PHY_CMN_CLK_CFG0 register is updated by the PHY driver and by two +divider clocks from Common Clock Framework: +devm_clk_hw_register_divider_parent_hw(). Concurrent access by the +clocks side is protected with spinlock, however driver's side in +restoring state is not. Restoring state is called from +msm_dsi_phy_enable(), so there could be a path leading to concurrent and +conflicting updates with clock framework. + +Add missing lock usage on the PHY driver side, encapsulated in its own +function so the code will be still readable. + +While shuffling the code, define and use PHY_CMN_CLK_CFG0 bitfields to +make the code more readable and obvious. + +Fixes: 1ef7c99d145c ("drm/msm/dsi: add support for 7nm DSI PHY/PLL") +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Signed-off-by: Krzysztof Kozlowski +Patchwork: https://patchwork.freedesktop.org/patch/637376/ +Link: https://lore.kernel.org/r/20250214-drm-msm-phy-pll-cfg-reg-v3-1-0943b850722c@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 14 ++++++++++++-- + .../gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 5 ++++- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +index 8e2af844d240d..31818549fedc1 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +@@ -372,6 +372,15 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) + ndelay(250); + } + ++static void dsi_pll_cmn_clk_cfg0_write(struct dsi_pll_7nm *pll, u32 val) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pll->postdiv_lock, flags); ++ writel(val, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); ++ spin_unlock_irqrestore(&pll->postdiv_lock, flags); ++} ++ + static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) + { + u32 data; +@@ -574,8 +583,9 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) + val |= cached->pll_out_div; + writel(val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + +- writel(cached->bit_clk_div | (cached->pix_clk_div << 4), +- phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); ++ dsi_pll_cmn_clk_cfg0_write(pll_7nm, ++ DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0(cached->bit_clk_div) | ++ DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4(cached->pix_clk_div)); + + val = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + val &= ~0x3; +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +index d54b72f924493..e0bf6e016b4ce 100644 +--- a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +@@ -9,7 +9,10 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> + + + +- ++ ++ ++ ++ + + + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg1-against-clo.patch b/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg1-against-clo.patch new file mode 100644 index 0000000000..ade3e3ebc4 --- /dev/null +++ b/queue-6.6/drm-msm-dsi-phy-protect-phy_cmn_clk_cfg1-against-clo.patch @@ -0,0 +1,144 @@ +From caa3fad17c9d98695ae4fe0bb11662163eedfb23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 16:08:42 +0100 +Subject: drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG1 against clock driver + +From: Krzysztof Kozlowski + +[ Upstream commit 5a97bc924ae0804b8dbf627e357acaa5ef761483 ] + +PHY_CMN_CLK_CFG1 register is updated by the PHY driver and by a mux +clock from Common Clock Framework: +devm_clk_hw_register_mux_parent_hws(). There could be a path leading to +concurrent and conflicting updates between PHY driver and clock +framework, e.g. changing the mux and enabling PLL clocks. + +Add dedicated spinlock to be sure all PHY_CMN_CLK_CFG1 updates are +synchronized. + +While shuffling the code, define and use PHY_CMN_CLK_CFG1 bitfields to +make the code more readable and obvious. + +Fixes: 1ef7c99d145c ("drm/msm/dsi: add support for 7nm DSI PHY/PLL") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/637378/ +Link: https://lore.kernel.org/r/20250214-drm-msm-phy-pll-cfg-reg-v3-2-0943b850722c@linaro.org +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 35 ++++++++++++------- + .../drm/msm/registers/display/dsi_phy_7nm.xml | 5 ++- + 2 files changed, 26 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +index 31818549fedc1..991bf10a64248 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +@@ -83,6 +83,9 @@ struct dsi_pll_7nm { + /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ + spinlock_t postdiv_lock; + ++ /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG1 register */ ++ spinlock_t pclk_mux_lock; ++ + struct pll_7nm_cached_state cached_state; + + struct dsi_pll_7nm *slave; +@@ -381,22 +384,32 @@ static void dsi_pll_cmn_clk_cfg0_write(struct dsi_pll_7nm *pll, u32 val) + spin_unlock_irqrestore(&pll->postdiv_lock, flags); + } + +-static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) ++static void dsi_pll_cmn_clk_cfg1_update(struct dsi_pll_7nm *pll, u32 mask, ++ u32 val) + { ++ unsigned long flags; + u32 data; + ++ spin_lock_irqsave(&pll->pclk_mux_lock, flags); + data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ data &= ~mask; ++ data |= val & mask; ++ ++ writel(data, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ spin_unlock_irqrestore(&pll->pclk_mux_lock, flags); ++} ++ ++static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) ++{ ++ dsi_pll_cmn_clk_cfg1_update(pll, DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN, 0); + } + + static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) + { +- u32 data; ++ u32 cfg_1 = DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN | DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN_SEL; + + writel(0x04, pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3); +- +- data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- writel(data | BIT(5) | BIT(4), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ dsi_pll_cmn_clk_cfg1_update(pll, cfg_1, cfg_1); + } + + static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) +@@ -574,7 +587,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) + { + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); + struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; +- void __iomem *phy_base = pll_7nm->phy->base; + u32 val; + int ret; + +@@ -586,11 +598,7 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) + dsi_pll_cmn_clk_cfg0_write(pll_7nm, + DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0(cached->bit_clk_div) | + DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4(cached->pix_clk_div)); +- +- val = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- val &= ~0x3; +- val |= cached->pll_mux; +- writel(val, phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ dsi_pll_cmn_clk_cfg1_update(pll_7nm, 0x3, cached->pll_mux); + + ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, + pll_7nm->vco_current_rate, +@@ -743,7 +751,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide + pll_by_2_bit, + }), 2, 0, pll_7nm->phy->base + + REG_DSI_7nm_PHY_CMN_CLK_CFG1, +- 0, 1, 0, NULL); ++ 0, 1, 0, &pll_7nm->pclk_mux_lock); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto fail; +@@ -788,6 +796,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) + pll_7nm_list[phy->id] = pll_7nm; + + spin_lock_init(&pll_7nm->postdiv_lock); ++ spin_lock_init(&pll_7nm->pclk_mux_lock); + + pll_7nm->phy = phy; + +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +index e0bf6e016b4ce..cfaf78c028b13 100644 +--- a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +@@ -13,7 +13,10 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> + + + +- ++ ++ ++ ++ + + + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-dsi-remove-dsi_phy_read-write.patch b/queue-6.6/drm-msm-dsi-remove-dsi_phy_read-write.patch new file mode 100644 index 0000000000..e6e0765cc7 --- /dev/null +++ b/queue-6.6/drm-msm-dsi-remove-dsi_phy_read-write.patch @@ -0,0 +1,2462 @@ +From 77afa715d224fbe18133d4b0ae3004bebb246a98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 00:36:59 +0200 +Subject: drm/msm/dsi: Remove dsi_phy_read/write() + +From: Konrad Dybcio + +[ Upstream commit 8fd6f64ddba041c3cf252f928b8c446a37996f39 ] + +These are dummy wrappers that do literally nothing interesting. +Remove them. + +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/590700/ +Link: https://lore.kernel.org/r/20240423-topic-msm_cleanup-v1-1-b30f39f43b90@linaro.org +Signed-off-by: Dmitry Baryshkov +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 2 - + drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 273 +++++++-------- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 215 ++++++------ + drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 109 +++--- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 224 ++++++------ + .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 205 ++++++----- + drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 320 +++++++++--------- + 7 files changed, 645 insertions(+), 703 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +index 1ff74689eefa0..31a481d02d8cc 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +@@ -12,8 +12,6 @@ + + #include "dsi.h" + +-#define dsi_phy_read(offset) readl((offset)) +-#define dsi_phy_write(offset, data) writel((data), (offset)) + #define dsi_phy_write_udelay(offset, data, delay_us) { writel((data), (offset)); udelay(delay_us); } + #define dsi_phy_write_ndelay(offset, data, delay_ns) { writel((data), (offset)); ndelay(delay_ns); } + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +index 27b592c776a30..677c625718119 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +@@ -187,20 +187,20 @@ static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config * + if (config->enable_ssc) { + pr_debug("SSC is enabled\n"); + +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1, +- config->ssc_stepsize & 0xff); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, +- config->ssc_stepsize >> 8); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1, +- config->ssc_div_per & 0xff); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1, +- config->ssc_div_per >> 8); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1, +- config->ssc_adj_per & 0xff); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1, +- config->ssc_adj_per >> 8); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL, +- SSC_EN | (config->ssc_center ? SSC_CENTER : 0)); ++ writel(config->ssc_stepsize & 0xff, ++ base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1); ++ writel(config->ssc_stepsize >> 8, ++ base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1); ++ writel(config->ssc_div_per & 0xff, ++ base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1); ++ writel(config->ssc_div_per >> 8, ++ base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1); ++ writel(config->ssc_adj_per & 0xff, ++ base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1); ++ writel(config->ssc_adj_per >> 8, ++ base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1); ++ writel(SSC_EN | (config->ssc_center ? SSC_CENTER : 0), ++ base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL); + } + } + +@@ -208,49 +208,43 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) + { + void __iomem *base = pll->phy->pll_base; + +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, +- 0xba); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, +- 0x0c); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, +- 0x08); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, +- 0xfa); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, +- 0x4c); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f); ++ writel(0x80, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE); ++ writel(0x03, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO); ++ writel(0x00, base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE); ++ writel(0x00, base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER); ++ writel(0x4e, base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER); ++ writel(0x40, base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS); ++ writel(0xba, base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE); ++ writel(0x0c, base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE); ++ writel(0x00, base + REG_DSI_10nm_PHY_PLL_OUTDIV); ++ writel(0x00, base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE); ++ writel(0x08, base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO); ++ writel(0x08, base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1); ++ writel(0xc0, base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1); ++ writel(0xfa, base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1); ++ writel(0x4c, base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1); ++ writel(0x80, base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE); ++ writel(0x29, base + REG_DSI_10nm_PHY_PLL_PFILT); ++ writel(0x3f, base + REG_DSI_10nm_PHY_PLL_IFILT); + } + + static void dsi_pll_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config) + { + void __iomem *base = pll->phy->pll_base; + +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1, +- config->decimal_div_start); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1, +- config->frac_div_start & 0xff); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1, +- (config->frac_div_start & 0xff00) >> 8); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1, +- (config->frac_div_start & 0x30000) >> 16); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, 64); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10); +- dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS, +- config->pll_clock_inverters); ++ writel(0x12, base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE); ++ writel(config->decimal_div_start, ++ base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1); ++ writel(config->frac_div_start & 0xff, ++ base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1); ++ writel((config->frac_div_start & 0xff00) >> 8, ++ base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1); ++ writel((config->frac_div_start & 0x30000) >> 16, ++ base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1); ++ writel(64, base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1); ++ writel(0x06, base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY); ++ writel(0x10, base + REG_DSI_10nm_PHY_PLL_CMODE); ++ writel(config->pll_clock_inverters, base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS); + } + + static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -305,21 +299,19 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) + + static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll) + { +- u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ u32 data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); + +- dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); +- dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0, +- data & ~BIT(5)); ++ writel(0, pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES); ++ writel(data & ~BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); + ndelay(250); + } + + static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll) + { +- u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ u32 data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); + +- dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0, +- data | BIT(5)); +- dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0); ++ writel(data | BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ writel(0xc0, pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES); + ndelay(250); + } + +@@ -327,18 +319,16 @@ static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll) + { + u32 data; + +- data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); +- dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, +- data & ~BIT(5)); ++ data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); ++ writel(data & ~BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + } + + static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) + { + u32 data; + +- data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); +- dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, +- data | BIT(5)); ++ data = readl(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); ++ writel(data | BIT(5), pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + } + + static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) +@@ -358,8 +348,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) + } + + /* Start PLL */ +- dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, +- 0x01); ++ writel(0x01, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL); + + /* + * ensure all PLL configurations are written prior to checking +@@ -380,11 +369,9 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) + if (pll_10nm->slave) + dsi_pll_enable_global_clk(pll_10nm->slave); + +- dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, +- 0x01); ++ writel(0x01, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL); + if (pll_10nm->slave) +- dsi_phy_write(pll_10nm->slave->phy->base + +- REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01); ++ writel(0x01, pll_10nm->slave->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL); + + error: + return rc; +@@ -392,7 +379,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) + + static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll) + { +- dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0); ++ writel(0, pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL); + dsi_pll_disable_pll_bias(pll); + } + +@@ -406,7 +393,7 @@ static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) + * powering down the PLL + */ + dsi_pll_disable_global_clk(pll_10nm); +- dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0); ++ writel(0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL); + dsi_pll_disable_sub(pll_10nm); + if (pll_10nm->slave) { + dsi_pll_disable_global_clk(pll_10nm->slave); +@@ -429,13 +416,13 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, + u32 dec; + u64 pll_freq, tmp64; + +- dec = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1); ++ dec = readl(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1); + dec &= 0xff; + +- frac = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1); +- frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) & ++ frac = readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1); ++ frac |= ((readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) & + 0xff) << 8); +- frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & ++ frac |= ((readl(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & + 0x3) << 16); + + /* +@@ -488,15 +475,15 @@ static void dsi_10nm_pll_save_state(struct msm_dsi_phy *phy) + void __iomem *phy_base = pll_10nm->phy->base; + u32 cmn_clk_cfg0, cmn_clk_cfg1; + +- cached->pll_out_div = dsi_phy_read(pll_10nm->phy->pll_base + ++ cached->pll_out_div = readl(pll_10nm->phy->pll_base + + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + cached->pll_out_div &= 0x3; + +- cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0); ++ cmn_clk_cfg0 = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0); + cached->bit_clk_div = cmn_clk_cfg0 & 0xf; + cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; + +- cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); ++ cmn_clk_cfg1 = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + cached->pll_mux = cmn_clk_cfg1 & 0x3; + + DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", +@@ -512,18 +499,18 @@ static int dsi_10nm_pll_restore_state(struct msm_dsi_phy *phy) + u32 val; + int ret; + +- val = dsi_phy_read(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); ++ val = readl(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + val &= ~0x3; + val |= cached->pll_out_div; +- dsi_phy_write(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val); ++ writel(val, pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + +- dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, +- cached->bit_clk_div | (cached->pix_clk_div << 4)); ++ writel(cached->bit_clk_div | (cached->pix_clk_div << 4), ++ phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0); + +- val = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); ++ val = readl(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + val &= ~0x3; + val |= cached->pll_mux; +- dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); ++ writel(val, phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + + ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw, + pll_10nm->vco_current_rate, +@@ -561,7 +548,7 @@ static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) + } + + /* set PLL src */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2)); ++ writel(data << 2, base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + + return 0; + } +@@ -724,7 +711,7 @@ static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy) + void __iomem *base = phy->base; + u32 data = 0; + +- data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL); ++ data = readl(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL); + mb(); /* make sure read happened */ + + return (data & BIT(0)); +@@ -740,11 +727,9 @@ static void dsi_phy_hw_v3_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable) + * corresponding to the logical data lane 0 + */ + if (enable) +- dsi_phy_write(lane_base + +- REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3); ++ writel(0x3, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0)); + else +- dsi_phy_write(lane_base + +- REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0); ++ writel(0, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0)); + } + + static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) +@@ -759,43 +744,40 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) + + /* Strength ctrl settings */ + for (i = 0; i < 5; i++) { +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPTX_STR_CTRL(i), +- 0x55); ++ writel(0x55, lane_base + REG_DSI_10nm_PHY_LN_LPTX_STR_CTRL(i)); + /* + * Disable LPRX and CDRX for all lanes. And later on, it will + * be only enabled for the physical data lane corresponding + * to the logical data lane 0 + */ +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(i), 0); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_PIN_SWAP(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_HSTX_STR_CTRL(i), +- 0x88); ++ writel(0, lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(i)); ++ writel(0x0, lane_base + REG_DSI_10nm_PHY_LN_PIN_SWAP(i)); ++ writel(0x88, lane_base + REG_DSI_10nm_PHY_LN_HSTX_STR_CTRL(i)); + } + + dsi_phy_hw_v3_0_config_lpcdrx(phy, true); + + /* other settings */ + for (i = 0; i < 5; i++) { +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG0(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG1(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i), +- i == 4 ? 0x80 : 0x0); ++ writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG0(i)); ++ writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG1(i)); ++ writel(0, lane_base + REG_DSI_10nm_PHY_LN_CFG2(i)); ++ writel(i == 4 ? 0x80 : 0x0, lane_base + REG_DSI_10nm_PHY_LN_CFG3(i)); + + /* platform specific dsi phy drive strength adjustment */ +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), +- tuning_cfg->rescode_offset_top[i]); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), +- tuning_cfg->rescode_offset_bot[i]); ++ writel(tuning_cfg->rescode_offset_top[i], ++ lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i)); ++ writel(tuning_cfg->rescode_offset_bot[i], ++ lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i)); + +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i), +- tx_dctrl[i]); ++ writel(tx_dctrl[i], ++ lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i)); + } + + if (!(phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)) { + /* Toggle BIT 0 to release freeze I/0 */ +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x05); +- dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04); ++ writel(0x05, lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3)); ++ writel(0x04, lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3)); + } + } + +@@ -833,64 +815,51 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, + + /* de-assert digital and pll power down */ + data = BIT(6) | BIT(5); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data); ++ writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0); + + /* Assert PLL core reset */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0x00); ++ writel(0x00, base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL); + + /* turn off resync FIFO */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x00); ++ writel(0x00, base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL); + + /* Select MS1 byte-clk */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10); ++ writel(0x10, base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL); + + /* Enable LDO with platform specific drive level/amplitude adjustment */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, +- tuning_cfg->vreg_ctrl); ++ writel(tuning_cfg->vreg_ctrl, base + REG_DSI_10nm_PHY_CMN_VREG_CTRL); + + /* Configure PHY lane swap (TODO: we need to calculate this) */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG1, 0x84); ++ writel(0x21, base + REG_DSI_10nm_PHY_CMN_LANE_CFG0); ++ writel(0x84, base + REG_DSI_10nm_PHY_CMN_LANE_CFG1); + + /* DSI PHY timings */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_0, +- timing->hs_halfbyte_en); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_1, +- timing->clk_zero); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_2, +- timing->clk_prepare); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_3, +- timing->clk_trail); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_4, +- timing->hs_exit); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_5, +- timing->hs_zero); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_6, +- timing->hs_prepare); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_7, +- timing->hs_trail); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_8, +- timing->hs_rqst); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_9, +- timing->ta_go | (timing->ta_sure << 3)); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_10, +- timing->ta_get); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_11, +- 0x00); ++ writel(timing->hs_halfbyte_en, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_0); ++ writel(timing->clk_zero, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_1); ++ writel(timing->clk_prepare, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_2); ++ writel(timing->clk_trail, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_3); ++ writel(timing->hs_exit, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_4); ++ writel(timing->hs_zero, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_5); ++ writel(timing->hs_prepare, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_6); ++ writel(timing->hs_trail, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_7); ++ writel(timing->hs_rqst, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_8); ++ writel(timing->ta_go | (timing->ta_sure << 3), base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_9); ++ writel(timing->ta_get, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_10); ++ writel(0x00, base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_11); + + /* Remove power down from all blocks */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x7f); ++ writel(0x7f, base + REG_DSI_10nm_PHY_CMN_CTRL_0); + + /* power up lanes */ +- data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ data = readl(base + REG_DSI_10nm_PHY_CMN_CTRL_0); + + /* TODO: only power up lanes that are used */ + data |= 0x1F; +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0x1F); ++ writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ writel(0x1F, base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0); + + /* Select full-rate mode */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_2, 0x40); ++ writel(0x40, base + REG_DSI_10nm_PHY_CMN_CTRL_2); + + ret = dsi_10nm_set_usecase(phy); + if (ret) { +@@ -918,15 +887,15 @@ static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy) + pr_warn("Turning OFF PHY while PLL is on\n"); + + dsi_phy_hw_v3_0_config_lpcdrx(phy, false); +- data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ data = readl(base + REG_DSI_10nm_PHY_CMN_CTRL_0); + + /* disable all lanes */ + data &= ~0x1F; +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data); +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0); ++ writel(data, base + REG_DSI_10nm_PHY_CMN_CTRL_0); ++ writel(0, base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0); + + /* Turn off all PHY blocks */ +- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x00); ++ writel(0x00, base + REG_DSI_10nm_PHY_CMN_CTRL_0); + /* make sure phy is turned off */ + wmb(); + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +index 31deda1c664ad..b128c4acea239 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +@@ -116,7 +116,7 @@ static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, + + tries = nb_tries; + while (tries--) { +- val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); ++ val = readl(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); + pll_locked = !!(val & BIT(5)); + + if (pll_locked) +@@ -130,7 +130,7 @@ static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, + + tries = nb_tries; + while (tries--) { +- val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); ++ val = readl(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); + pll_ready = !!(val & BIT(0)); + + if (pll_ready) +@@ -288,29 +288,29 @@ static void pll_db_commit_ssc(struct dsi_pll_14nm *pll, struct dsi_pll_config *p + + data = pconf->ssc_adj_period; + data &= 0x0ff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1); + data = (pconf->ssc_adj_period >> 8); + data &= 0x03; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2); + + data = pconf->ssc_period; + data &= 0x0ff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_PER1); + data = (pconf->ssc_period >> 8); + data &= 0x0ff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_PER2); + + data = pconf->ssc_step_size; + data &= 0x0ff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1); + data = (pconf->ssc_step_size >> 8); + data &= 0x0ff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2); + + data = (pconf->ssc_center & 0x01); + data <<= 1; + data |= 0x01; /* enable */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER); + + wmb(); /* make sure register committed */ + } +@@ -323,43 +323,45 @@ static void pll_db_commit_common(struct dsi_pll_14nm *pll, + + /* confgiure the non frequency dependent pll registers */ + data = 0; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, 1); ++ writel(1, base + REG_DSI_14nm_PHY_PLL_TXCLK_EN); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, 48); +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, 4 << 3); /* bandgap_timer */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, 5); /* pll_wakeup_timer */ ++ writel(48, base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL); ++ /* bandgap_timer */ ++ writel(4 << 3, base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2); ++ /* pll_wakeup_timer */ ++ writel(5, base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5); + + data = pconf->pll_vco_div_ref & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1); + data = (pconf->pll_vco_div_ref >> 8) & 0x3; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2); + + data = pconf->pll_kvco_div_ref & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1); + data = (pconf->pll_kvco_div_ref >> 8) & 0x3; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, 16); ++ writel(16, base + REG_DSI_14nm_PHY_PLL_PLL_MISC1); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, 4); ++ writel(4, base + REG_DSI_14nm_PHY_PLL_IE_TRIM); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, 4); ++ writel(4, base + REG_DSI_14nm_PHY_PLL_IP_TRIM); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, 1 << 3 | 1); ++ writel(1 << 3 | 1, base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, 0 << 3 | 0); ++ writel(0 << 3 | 0, base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, 0 << 3 | 0); ++ writel(0 << 3 | 0, base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, 4 << 3 | 4); ++ writel(4 << 3 | 4, base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, 1 << 4 | 11); ++ writel(1 << 4 | 11, base + REG_DSI_14nm_PHY_PLL_PLL_LPF1); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, 7); ++ writel(7, base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, 1 << 4 | 2); ++ writel(1 << 4 | 2, base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL); + } + + static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) +@@ -369,13 +371,13 @@ static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) + /* de assert pll start and apply pll sw reset */ + + /* stop pll */ +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); ++ writel(0, cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL); + + /* pll sw reset */ + dsi_phy_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10); + wmb(); /* make sure register committed */ + +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0); ++ writel(0, cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1); + wmb(); /* make sure register committed */ + } + +@@ -388,50 +390,50 @@ static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, + + DBG("DSI%d PLL", pll->phy->id); + +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, 0x3c); ++ writel(0x3c, cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL); + + pll_db_commit_common(pll, pconf); + + pll_14nm_software_reset(pll); + + /* Use the /2 path in Mux */ +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, 1); ++ writel(1, cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1); + + data = 0xff; /* data, clk, pll normal operation */ +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data); ++ writel(data, cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0); + + /* configure the frequency dependent pll registers */ + data = pconf->dec_start; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_DEC_START); + + data = pconf->div_frac_start & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1); + data = (pconf->div_frac_start >> 8) & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2); + data = (pconf->div_frac_start >> 16) & 0xf; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3); + + data = pconf->plllock_cmp & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1); + + data = (pconf->plllock_cmp >> 8) & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2); + + data = (pconf->plllock_cmp >> 16) & 0x3; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3); + + data = pconf->plllock_cnt << 1 | 0 << 3; /* plllock_rng */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN); + + data = pconf->pll_vco_count & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1); + data = (pconf->pll_vco_count >> 8) & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2); + + data = pconf->pll_kvco_count & 0xff; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1); + data = (pconf->pll_kvco_count >> 8) & 0x3; +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data); ++ writel(data, base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2); + + /* + * High nibble configures the post divider internal to the VCO. It's +@@ -442,7 +444,7 @@ static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, + * 2: divided by 4 + * 3: divided by 8 + */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, 0 << 4 | 3); ++ writel(0 << 4 | 3, base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV); + + if (pconf->ssc_en) + pll_db_commit_ssc(pll, pconf); +@@ -497,16 +499,16 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, + u32 dec_start; + u64 ref_clk = parent_rate; + +- dec_start = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DEC_START); ++ dec_start = readl(base + REG_DSI_14nm_PHY_PLL_DEC_START); + dec_start &= 0x0ff; + + DBG("dec_start = %x", dec_start); + +- div_frac_start = (dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3) ++ div_frac_start = (readl(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3) + & 0xf) << 16; +- div_frac_start |= (dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2) ++ div_frac_start |= (readl(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2) + & 0xff) << 8; +- div_frac_start |= dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1) ++ div_frac_start |= readl(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1) + & 0xff; + + DBG("div_frac_start = %x", div_frac_start); +@@ -542,8 +544,8 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) + if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0) + dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); ++ writel(0x10, base + REG_DSI_14nm_PHY_PLL_VREF_CFG1); ++ writel(1, cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL); + + locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, + POLL_TIMEOUT_US); +@@ -569,7 +571,7 @@ static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw) + if (unlikely(!pll_14nm->phy->pll_on)) + return; + +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); ++ writel(0, cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL); + + pll_14nm->phy->pll_on = false; + } +@@ -611,7 +613,7 @@ static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, + + DBG("DSI%d PLL parent rate=%lu", pll_14nm->phy->id, parent_rate); + +- val = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; ++ val = readl(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; + val &= div_mask(width); + + return divider_recalc_rate(hw, parent_rate, val, NULL, +@@ -653,11 +655,11 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + + spin_lock_irqsave(lock, flags); + +- val = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); ++ val = readl(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + val &= ~(div_mask(width) << shift); + + val |= value << shift; +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); ++ writel(val, base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + + /* If we're master in bonded DSI mode, then the slave PLL's post-dividers + * follow the master's post dividers +@@ -666,7 +668,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; + void __iomem *slave_base = pll_14nm_slave->phy->base; + +- dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); ++ writel(val, slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + } + + spin_unlock_irqrestore(lock, flags); +@@ -691,7 +693,7 @@ static void dsi_14nm_pll_save_state(struct msm_dsi_phy *phy) + void __iomem *cmn_base = pll_14nm->phy->base; + u32 data; + +- data = dsi_phy_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); ++ data = readl(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + + cached_state->n1postdiv = data & 0xf; + cached_state->n2postdiv = (data >> 4) & 0xf; +@@ -723,14 +725,14 @@ static int dsi_14nm_pll_restore_state(struct msm_dsi_phy *phy) + DBG("DSI%d PLL restore state %x %x", pll_14nm->phy->id, + cached_state->n1postdiv, cached_state->n2postdiv); + +- dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); ++ writel(data, cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + + /* also restore post-dividers for slave DSI PLL */ + if (phy->usecase == MSM_DSI_PHY_MASTER) { + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; + void __iomem *slave_base = pll_14nm_slave->phy->base; + +- dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); ++ writel(data, slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + } + + return 0; +@@ -758,9 +760,9 @@ static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) + return -EINVAL; + } + +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en); ++ writel(clkbuflr_en, base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN); + if (bandgap) +- dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap); ++ writel(bandgap, base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP); + + return 0; + } +@@ -917,27 +919,27 @@ static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy, + u32 halfbyte_en = clk_ln ? timing->hs_halfbyte_en_ckln : + timing->hs_halfbyte_en; + +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_4(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT(timing->hs_exit)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_5(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO(zero)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_6(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE(prepare)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_7(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL(trail)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_8(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST(rqst)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG0(lane_idx), +- DSI_14nm_PHY_LN_CFG0_PREPARE_DLY(prep_dly)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG1(lane_idx), +- halfbyte_en ? DSI_14nm_PHY_LN_CFG1_HALFBYTECLK_EN : 0); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_9(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO(timing->ta_go) | +- DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE(timing->ta_sure)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_10(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET(timing->ta_get)); +- dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_11(lane_idx), +- DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(0xa0)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT(timing->hs_exit), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_4(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO(zero), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_5(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE(prepare), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_6(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL(trail), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_7(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST(rqst), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_8(lane_idx)); ++ writel(DSI_14nm_PHY_LN_CFG0_PREPARE_DLY(prep_dly), ++ base + REG_DSI_14nm_PHY_LN_CFG0(lane_idx)); ++ writel(halfbyte_en ? DSI_14nm_PHY_LN_CFG1_HALFBYTECLK_EN : 0, ++ base + REG_DSI_14nm_PHY_LN_CFG1(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO(timing->ta_go) | ++ DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE(timing->ta_sure), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_9(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET(timing->ta_get), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_10(lane_idx)); ++ writel(DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(0xa0), ++ base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_11(lane_idx)); + } + + static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, +@@ -961,49 +963,44 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, + data = 0x1c; + if (phy->usecase != MSM_DSI_PHY_STANDALONE) + data |= DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL(32); +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); ++ writel(data, base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL); + +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0x1); ++ writel(0x1, base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); + + /* 4 data lanes + 1 clk lane configuration */ + for (i = 0; i < 5; i++) { +- dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_VREG_CNTRL(i), +- 0x1d); +- +- dsi_phy_write(lane_base + +- REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_0(i), 0xff); +- dsi_phy_write(lane_base + +- REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_1(i), +- (i == PHY_14NM_CKLN_IDX) ? 0x00 : 0x06); +- +- dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG3(i), +- (i == PHY_14NM_CKLN_IDX) ? 0x8f : 0x0f); +- dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG2(i), 0x10); +- dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_DATAPATH(i), +- 0); +- dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_STR(i), +- 0x88); ++ writel(0x1d, lane_base + REG_DSI_14nm_PHY_LN_VREG_CNTRL(i)); ++ ++ writel(0xff, lane_base + REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_0(i)); ++ writel(i == PHY_14NM_CKLN_IDX ? 0x00 : 0x06, ++ lane_base + REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_1(i)); ++ ++ writel(i == PHY_14NM_CKLN_IDX ? 0x8f : 0x0f, ++ lane_base + REG_DSI_14nm_PHY_LN_CFG3(i)); ++ writel(0x10, lane_base + REG_DSI_14nm_PHY_LN_CFG2(i)); ++ writel(0, lane_base + REG_DSI_14nm_PHY_LN_TEST_DATAPATH(i)); ++ writel(0x88, lane_base + REG_DSI_14nm_PHY_LN_TEST_STR(i)); + + dsi_14nm_dphy_set_timing(phy, timing, i); + } + + /* Make sure PLL is not start */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0x00); ++ writel(0x00, base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL); + + wmb(); /* make sure everything is written before reset and enable */ + + /* reset digital block */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x80); ++ writel(0x80, base + REG_DSI_14nm_PHY_CMN_CTRL_1); + wmb(); /* ensure reset is asserted */ + udelay(100); +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00); ++ writel(0x00, base + REG_DSI_14nm_PHY_CMN_CTRL_1); + +- glbl_test_ctrl = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); ++ glbl_test_ctrl = readl(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE) + glbl_test_ctrl |= DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + glbl_test_ctrl &= ~DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, glbl_test_ctrl); ++ writel(glbl_test_ctrl, base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); + ret = dsi_14nm_set_usecase(phy); + if (ret) { + DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", +@@ -1012,15 +1009,15 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, + } + + /* Remove power down from PLL and all lanes */ +- dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0xff); ++ writel(0xff, base + REG_DSI_14nm_PHY_CMN_CTRL_0); + + return 0; + } + + static void dsi_14nm_phy_disable(struct msm_dsi_phy *phy) + { +- dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0); +- dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0); ++ writel(0, phy->base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); ++ writel(0, phy->base + REG_DSI_14nm_PHY_CMN_CTRL_0); + + /* ensure that the phy is completely disabled */ + wmb(); +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +index c9752b9917445..cee34b76c3d21 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +@@ -12,32 +12,32 @@ static void dsi_20nm_dphy_set_timing(struct msm_dsi_phy *phy, + { + void __iomem *base = phy->base; + +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_0, +- DSI_20nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_1, +- DSI_20nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_2, +- DSI_20nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare)); ++ writel(DSI_20nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_0); ++ writel(DSI_20nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_1); ++ writel(DSI_20nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_2); + if (timing->clk_zero & BIT(8)) +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_3, +- DSI_20nm_PHY_TIMING_CTRL_3_CLK_ZERO_8); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_4, +- DSI_20nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_5, +- DSI_20nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_6, +- DSI_20nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_7, +- DSI_20nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_8, +- DSI_20nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_9, +- DSI_20nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | +- DSI_20nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_10, +- DSI_20nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get)); +- dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_11, +- DSI_20nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0)); ++ writel(DSI_20nm_PHY_TIMING_CTRL_3_CLK_ZERO_8, ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_3); ++ writel(DSI_20nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_4); ++ writel(DSI_20nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_5); ++ writel(DSI_20nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_6); ++ writel(DSI_20nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_7); ++ writel(DSI_20nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_8); ++ writel(DSI_20nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | ++ DSI_20nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_9); ++ writel(DSI_20nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_10); ++ writel(DSI_20nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0), ++ base + REG_DSI_20nm_PHY_TIMING_CTRL_11); + } + + static void dsi_20nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) +@@ -45,23 +45,23 @@ static void dsi_20nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) + void __iomem *base = phy->reg_base; + + if (!enable) { +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG, 0); ++ writel(0, base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG); + return; + } + + if (phy->regulator_ldo_mode) { +- dsi_phy_write(phy->base + REG_DSI_20nm_PHY_LDO_CNTRL, 0x1d); ++ writel(0x1d, phy->base + REG_DSI_20nm_PHY_LDO_CNTRL); + return; + } + + /* non LDO mode */ +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_1, 0x03); +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_2, 0x03); +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_3, 0x00); +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_4, 0x20); +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG, 0x01); +- dsi_phy_write(phy->base + REG_DSI_20nm_PHY_LDO_CNTRL, 0x00); +- dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_0, 0x03); ++ writel(0x03, base + REG_DSI_20nm_PHY_REGULATOR_CTRL_1); ++ writel(0x03, base + REG_DSI_20nm_PHY_REGULATOR_CTRL_2); ++ writel(0x00, base + REG_DSI_20nm_PHY_REGULATOR_CTRL_3); ++ writel(0x20, base + REG_DSI_20nm_PHY_REGULATOR_CTRL_4); ++ writel(0x01, base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG); ++ writel(0x00, phy->base + REG_DSI_20nm_PHY_LDO_CNTRL); ++ writel(0x03, base + REG_DSI_20nm_PHY_REGULATOR_CTRL_0); + } + + static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, +@@ -83,49 +83,48 @@ static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, + + dsi_20nm_phy_regulator_ctrl(phy, true); + +- dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_0, 0xff); ++ writel(0xff, base + REG_DSI_20nm_PHY_STRENGTH_0); + +- val = dsi_phy_read(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL); ++ val = readl(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_STANDALONE) + val |= DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + val &= ~DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; +- dsi_phy_write(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL, val); ++ writel(val, base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL); + + for (i = 0; i < 4; i++) { +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_3(i), +- (i >> 1) * 0x40); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_TEST_STR_0(i), 0x01); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_TEST_STR_1(i), 0x46); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_0(i), 0x02); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_1(i), 0xa0); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_4(i), cfg_4[i]); ++ writel((i >> 1) * 0x40, base + REG_DSI_20nm_PHY_LN_CFG_3(i)); ++ writel(0x01, base + REG_DSI_20nm_PHY_LN_TEST_STR_0(i)); ++ writel(0x46, base + REG_DSI_20nm_PHY_LN_TEST_STR_1(i)); ++ writel(0x02, base + REG_DSI_20nm_PHY_LN_CFG_0(i)); ++ writel(0xa0, base + REG_DSI_20nm_PHY_LN_CFG_1(i)); ++ writel(cfg_4[i], base + REG_DSI_20nm_PHY_LN_CFG_4(i)); + } + +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_3, 0x80); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_TEST_STR0, 0x01); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_TEST_STR1, 0x46); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_0, 0x00); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_1, 0xa0); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_2, 0x00); +- dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_4, 0x00); ++ writel(0x80, base + REG_DSI_20nm_PHY_LNCK_CFG_3); ++ writel(0x01, base + REG_DSI_20nm_PHY_LNCK_TEST_STR0); ++ writel(0x46, base + REG_DSI_20nm_PHY_LNCK_TEST_STR1); ++ writel(0x00, base + REG_DSI_20nm_PHY_LNCK_CFG_0); ++ writel(0xa0, base + REG_DSI_20nm_PHY_LNCK_CFG_1); ++ writel(0x00, base + REG_DSI_20nm_PHY_LNCK_CFG_2); ++ writel(0x00, base + REG_DSI_20nm_PHY_LNCK_CFG_4); + + dsi_20nm_dphy_set_timing(phy, timing); + +- dsi_phy_write(base + REG_DSI_20nm_PHY_CTRL_1, 0x00); ++ writel(0x00, base + REG_DSI_20nm_PHY_CTRL_1); + +- dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_1, 0x06); ++ writel(0x06, base + REG_DSI_20nm_PHY_STRENGTH_1); + + /* make sure everything is written before enable */ + wmb(); +- dsi_phy_write(base + REG_DSI_20nm_PHY_CTRL_0, 0x7f); ++ writel(0x7f, base + REG_DSI_20nm_PHY_CTRL_0); + + return 0; + } + + static void dsi_20nm_phy_disable(struct msm_dsi_phy *phy) + { +- dsi_phy_write(phy->base + REG_DSI_20nm_PHY_CTRL_0, 0); ++ writel(0, phy->base + REG_DSI_20nm_PHY_CTRL_0); + dsi_20nm_phy_regulator_ctrl(phy, false); + } + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +index ceec7bb87bf13..b3e914954f4a4 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +@@ -83,7 +83,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, + u32 val; + + while (nb_tries--) { +- val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS); ++ val = readl(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS); + pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY); + + if (pll_locked) +@@ -128,7 +128,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + VERB("rate=%lu, parent's=%lu", rate, parent_rate); + + /* Force postdiv2 to be div-4 */ +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3); ++ writel(3, base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG); + + /* Configure the Loop filter resistance */ + for (i = 0; i < LPFR_LUT_SIZE; i++) +@@ -139,11 +139,11 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + rate); + return -EINVAL; + } +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance); ++ writel(lpfr_lut[i].resistance, base + REG_DSI_28nm_PHY_PLL_LPFR_CFG); + + /* Loop filter capacitance values : c1 and c2 */ +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15); ++ writel(0x70, base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG); ++ writel(0x15, base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG); + + rem = rate % VCO_REF_CLK_RATE; + if (rem) { +@@ -168,7 +168,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + + DBG("Generated VCO Clock: %lu", gen_vco_clk); + rem = 0; +- sdm_cfg1 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); ++ sdm_cfg1 = readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); + sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK; + if (frac_n_mode) { + sdm_cfg0 = 0x0; +@@ -195,17 +195,17 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000); + DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3, 0x2b); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4, 0x06); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); ++ writel(0x02, base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG); ++ writel(0x2b, base + REG_DSI_28nm_PHY_PLL_CAL_CFG3); ++ writel(0x06, base + REG_DSI_28nm_PHY_PLL_CAL_CFG4); ++ writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2, +- DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3, +- DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); ++ writel(sdm_cfg1, base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); ++ writel(DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2), ++ base + REG_DSI_28nm_PHY_PLL_SDM_CFG2); ++ writel(DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3), ++ base + REG_DSI_28nm_PHY_PLL_SDM_CFG3); ++ writel(0, base + REG_DSI_28nm_PHY_PLL_SDM_CFG4); + + /* Add hardware recommended delay for correct PLL configuration */ + if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) +@@ -213,18 +213,18 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + else + udelay(1); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0, sdm_cfg0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0, 0x12); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6, 0x30); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8, 0x60); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10, cal_cfg10 & 0xff); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11, cal_cfg11 & 0xff); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG, 0x20); ++ writel(refclk_cfg, base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG); ++ writel(0x00, base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG); ++ writel(0x31, base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG); ++ writel(sdm_cfg0, base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); ++ writel(0x12, base + REG_DSI_28nm_PHY_PLL_CAL_CFG0); ++ writel(0x30, base + REG_DSI_28nm_PHY_PLL_CAL_CFG6); ++ writel(0x00, base + REG_DSI_28nm_PHY_PLL_CAL_CFG7); ++ writel(0x60, base + REG_DSI_28nm_PHY_PLL_CAL_CFG8); ++ writel(0x00, base + REG_DSI_28nm_PHY_PLL_CAL_CFG9); ++ writel(cal_cfg10 & 0xff, base + REG_DSI_28nm_PHY_PLL_CAL_CFG10); ++ writel(cal_cfg11 & 0xff, base + REG_DSI_28nm_PHY_PLL_CAL_CFG11); ++ writel(0x20, base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG); + + return 0; + } +@@ -250,27 +250,27 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, + VERB("parent_rate=%lu", parent_rate); + + /* Check to see if the ref clk doubler is enabled */ +- doubler = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) & ++ doubler = readl(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) & + DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; + ref_clk += (doubler * VCO_REF_CLK_RATE); + + /* see if it is integer mode or sdm mode */ +- sdm0 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); ++ sdm0 = readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); + if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) { + /* integer mode */ + sdm_byp_div = FIELD( +- dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0), ++ readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0), + DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1; + vco_rate = ref_clk * sdm_byp_div; + } else { + /* sdm mode */ + sdm_dc_off = FIELD( +- dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1), ++ readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1), + DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET); + DBG("sdm_dc_off = %d", sdm_dc_off); +- sdm2 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2), ++ sdm2 = FIELD(readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2), + DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0); +- sdm3 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3), ++ sdm3 = FIELD(readl(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3), + DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8); + sdm_freq_seed = (sdm3 << 8) | sdm2; + DBG("sdm_freq_seed = %d", sdm_freq_seed); +@@ -318,7 +318,7 @@ static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm) + /* DSI Uniphy lock detect setting */ + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, + 0x0c, 100); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); ++ writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2); + + /* poll for PLL ready status */ + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, +@@ -396,7 +396,7 @@ static int dsi_pll_28nm_vco_prepare_8226(struct clk_hw *hw) + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34); ++ writel(0x34, base + REG_DSI_28nm_PHY_PLL_CAL_CFG1); + + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); +@@ -410,10 +410,10 @@ static int dsi_pll_28nm_vco_prepare_8226(struct clk_hw *hw) + + for (i = 0; i < 7; i++) { + /* DSI Uniphy lock detect setting */ +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); ++ writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2); + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, + 0x0c, 100); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); ++ writel(0x0d, base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2); + + /* poll for PLL ready status */ + locked = pll_28nm_poll_for_ready(pll_28nm, +@@ -504,7 +504,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) + if (unlikely(!pll_28nm->phy->pll_on)) + return; + +- dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); ++ writel(0, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG); + + pll_28nm->phy->pll_on = false; + } +@@ -560,10 +560,10 @@ static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy) + void __iomem *base = pll_28nm->phy->pll_base; + + cached_state->postdiv3 = +- dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); ++ readl(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); + cached_state->postdiv1 = +- dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); +- cached_state->byte_mux = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); ++ readl(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); ++ cached_state->byte_mux = readl(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); + if (dsi_pll_28nm_clk_is_enabled(phy->vco_hw)) + cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); + else +@@ -585,12 +585,9 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) + return ret; + } + +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, +- cached_state->postdiv3); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, +- cached_state->postdiv1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG, +- cached_state->byte_mux); ++ writel(cached_state->postdiv3, base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); ++ writel(cached_state->postdiv1, base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); ++ writel(cached_state->byte_mux, base + REG_DSI_28nm_PHY_PLL_VREG_CFG); + + return 0; + } +@@ -700,72 +697,71 @@ static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, + { + void __iomem *base = phy->base; + +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_0, +- DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1, +- DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2, +- DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare)); ++ writel(DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_0); ++ writel(DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_1); ++ writel(DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_2); + if (timing->clk_zero & BIT(8)) +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3, +- DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4, +- DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5, +- DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6, +- DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7, +- DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8, +- DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9, +- DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | +- DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10, +- DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get)); +- dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11, +- DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0)); ++ writel(DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8, ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_3); ++ writel(DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_4); ++ writel(DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_5); ++ writel(DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_6); ++ writel(DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_7); ++ writel(DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_8); ++ writel(DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | ++ DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_9); ++ writel(DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_10); ++ writel(DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0), ++ base + REG_DSI_28nm_PHY_TIMING_CTRL_11); + } + + static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy) + { + void __iomem *base = phy->reg_base; + +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20); +- dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00); ++ writel(0x0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0); ++ writel(1, base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG); ++ writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5); ++ writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3); ++ writel(0x3, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2); ++ writel(0x9, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1); ++ writel(0x7, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0); ++ writel(0x20, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4); ++ writel(0x00, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL); + } + + static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy) + { + void __iomem *base = phy->reg_base; + +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20); ++ writel(0x0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0); ++ writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG); ++ writel(0x7, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5); ++ writel(0, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3); ++ writel(0x1, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2); ++ writel(0x1, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1); ++ writel(0x20, base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4); + + if (phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) +- dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05); ++ writel(0x05, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL); + else +- dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d); ++ writel(0x0d, phy->base + REG_DSI_28nm_PHY_LDO_CNTRL); + } + + static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) + { + if (!enable) { +- dsi_phy_write(phy->reg_base + +- REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0); ++ writel(0, phy->reg_base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG); + return; + } + +@@ -792,49 +788,49 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, + return -EINVAL; + } + +- dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff); ++ writel(0xff, base + REG_DSI_28nm_PHY_STRENGTH_0); + + dsi_28nm_phy_regulator_ctrl(phy, true); + + dsi_28nm_dphy_set_timing(phy, timing); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f); ++ writel(0x00, base + REG_DSI_28nm_PHY_CTRL_1); ++ writel(0x5f, base + REG_DSI_28nm_PHY_CTRL_0); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6); ++ writel(0x6, base + REG_DSI_28nm_PHY_STRENGTH_1); + + for (i = 0; i < 4; i++) { +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97); ++ writel(0, base + REG_DSI_28nm_PHY_LN_CFG_0(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_CFG_1(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_CFG_2(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_CFG_3(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_CFG_4(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i)); ++ writel(0, base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i)); ++ writel(0x1, base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i)); ++ writel(0x97, base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i)); + } + +- dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_4, 0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1); +- dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb); ++ writel(0, base + REG_DSI_28nm_PHY_LNCK_CFG_4); ++ writel(0xc0, base + REG_DSI_28nm_PHY_LNCK_CFG_1); ++ writel(0x1, base + REG_DSI_28nm_PHY_LNCK_TEST_STR0); ++ writel(0xbb, base + REG_DSI_28nm_PHY_LNCK_TEST_STR1); + +- dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f); ++ writel(0x5f, base + REG_DSI_28nm_PHY_CTRL_0); + +- val = dsi_phy_read(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL); ++ val = readl(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE) + val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; +- dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, val); ++ writel(val, base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL); + + return 0; + } + + static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy) + { +- dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0); ++ writel(0, phy->base + REG_DSI_28nm_PHY_CTRL_0); + dsi_28nm_phy_regulator_ctrl(phy, false); + + /* +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +index 26c08047e20c8..5311ab7f3c709 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +@@ -74,7 +74,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, + u32 val; + + while (nb_tries--) { +- val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_RDY); ++ val = readl(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_RDY); + pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY); + + if (pll_locked) +@@ -103,30 +103,25 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + val = VCO_REF_CLK_RATE / 10; + fb_divider = (temp * VCO_PREF_DIV_RATIO) / val; + fb_divider = fb_divider / 2 - 1; +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1, +- fb_divider & 0xff); ++ writel(fb_divider & 0xff, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); + +- val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); ++ val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); + + val |= (fb_divider >> 8) & 0x07; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2, +- val); ++ writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); + +- val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); ++ val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); + + val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3, +- val); ++ writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6, +- 0xf); ++ writel(0xf, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6); + +- val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); ++ val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + val |= 0x7 << 4; +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, +- val); ++ writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + + return 0; + } +@@ -149,16 +144,16 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, + + VERB("parent_rate=%lu", parent_rate); + +- status = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); ++ status = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); + + if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) { +- fb_divider = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); ++ fb_divider = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); + fb_divider &= 0xff; +- temp = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07; ++ temp = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07; + fb_divider = (temp << 8) | fb_divider; + fb_divider += 1; + +- ref_divider = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); ++ ref_divider = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); + ref_divider &= 0x3f; + ref_divider += 1; + +@@ -195,18 +190,18 @@ static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) + * 2: divide by 8 to get bit clock divider + * 3: write it to POSTDIV1 + */ +- val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); ++ val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); + byte_div = val + 1; + bit_div = byte_div / 8; + +- val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); ++ val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + val &= ~0xf; + val |= (bit_div - 1); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val); ++ writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + + /* enable the PLL */ +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, +- DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE); ++ writel(DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE, ++ base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); + + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); + +@@ -230,7 +225,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) + if (unlikely(!pll_28nm->phy->pll_on)) + return; + +- dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); ++ writel(0x00, pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); + + pll_28nm->phy->pll_on = false; + } +@@ -277,7 +272,7 @@ static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw, + struct clk_bytediv *bytediv = to_clk_bytediv(hw); + unsigned int div; + +- div = dsi_phy_read(bytediv->reg) & 0xff; ++ div = readl(bytediv->reg) & 0xff; + + return parent_rate / (div + 1); + } +@@ -323,9 +318,9 @@ static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate, + + factor = get_vco_mul_factor(rate); + +- val = dsi_phy_read(bytediv->reg); ++ val = readl(bytediv->reg); + val |= (factor - 1) & 0xff; +- dsi_phy_write(bytediv->reg, val); ++ writel(val, bytediv->reg); + + return 0; + } +@@ -347,11 +342,11 @@ static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy) + void __iomem *base = pll_28nm->phy->pll_base; + + cached_state->postdiv3 = +- dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); ++ readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); + cached_state->postdiv2 = +- dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); ++ readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); + cached_state->postdiv1 = +- dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); ++ readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + + cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); + } +@@ -371,12 +366,9 @@ static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) + return ret; + } + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, +- cached_state->postdiv3); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9, +- cached_state->postdiv2); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, +- cached_state->postdiv1); ++ writel(cached_state->postdiv3, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); ++ writel(cached_state->postdiv2, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); ++ writel(cached_state->postdiv1, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + + return 0; + } +@@ -477,53 +469,52 @@ static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, + { + void __iomem *base = phy->base; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0, +- DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1, +- DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2, +- DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4, +- DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5, +- DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6, +- DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7, +- DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8, +- DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9, +- DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | +- DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10, +- DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get)); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11, +- DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0)); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2); ++ writel(0, base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | ++ DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10); ++ writel(DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0), ++ base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11); + } + + static void dsi_28nm_phy_regulator_init(struct msm_dsi_phy *phy) + { + void __iomem *base = phy->reg_base; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 1); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 1); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4, +- 0x100); ++ writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0); ++ writel(1, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1); ++ writel(1, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2); ++ writel(0, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3); ++ writel(0x100, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4); + } + + static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy) + { + void __iomem *base = phy->reg_base; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 0xa); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 0x4); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4, 0x20); ++ writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0); ++ writel(0xa, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1); ++ writel(0x4, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3); ++ writel(0x20, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4); + } + + static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy) +@@ -532,21 +523,20 @@ static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy) + u32 status; + int i = 5000; + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG, +- 0x3); ++ writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG); + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1, 0x5a); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3, 0x10); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4, 0x1); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0, 0x1); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2); ++ writel(0x5a, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1); ++ writel(0x10, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3); ++ writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4); ++ writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0); + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x1); ++ writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER); + usleep_range(5000, 6000); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x0); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER); + + do { +- status = dsi_phy_read(base + ++ status = readl(base + + REG_DSI_28nm_8960_PHY_MISC_CAL_STATUS); + + if (!(status & DSI_28nm_8960_PHY_MISC_CAL_STATUS_CAL_BUSY)) +@@ -562,23 +552,20 @@ static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy) + int i; + + for (i = 0; i < 4; i++) { +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i), 0x80); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i), 0x45); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i), 0x00); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i), +- 0x00); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i), +- 0x01); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i), +- 0x66); ++ writel(0x80, base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i)); ++ writel(0x45, base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i)); ++ writel(0x00, base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i)); ++ writel(0x00, base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i)); ++ writel(0x01, base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i)); ++ writel(0x66, base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i)); + } + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0, 0x40); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1, 0x67); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH, 0x0); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0, 0x1); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1, 0x88); ++ writel(0x40, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0); ++ writel(0x67, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH); ++ writel(0x1, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0); ++ writel(0x88, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1); + } + + static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, +@@ -598,18 +585,18 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, + + dsi_28nm_phy_regulator_init(phy); + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LDO_CTRL, 0x04); ++ writel(0x04, base + REG_DSI_28nm_8960_PHY_LDO_CTRL); + + /* strength control */ +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_0, 0xff); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_1, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_2, 0x06); ++ writel(0xff, base + REG_DSI_28nm_8960_PHY_STRENGTH_0); ++ writel(0x00, base + REG_DSI_28nm_8960_PHY_STRENGTH_1); ++ writel(0x06, base + REG_DSI_28nm_8960_PHY_STRENGTH_2); + + /* phy ctrl */ +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x5f); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_1, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_2, 0x00); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_3, 0x10); ++ writel(0x5f, base + REG_DSI_28nm_8960_PHY_CTRL_0); ++ writel(0x00, base + REG_DSI_28nm_8960_PHY_CTRL_1); ++ writel(0x00, base + REG_DSI_28nm_8960_PHY_CTRL_2); ++ writel(0x10, base + REG_DSI_28nm_8960_PHY_CTRL_3); + + dsi_28nm_phy_regulator_ctrl(phy); + +@@ -617,10 +604,10 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, + + dsi_28nm_phy_lane_config(phy); + +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0f); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1, 0x03); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0, 0x03); +- dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0); ++ writel(0x0f, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4); ++ writel(0x03, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1); ++ writel(0x03, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0); ++ writel(0x0, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4); + + dsi_28nm_dphy_set_timing(phy, timing); + +@@ -629,7 +616,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, + + static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy) + { +- dsi_phy_write(phy->base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x0); ++ writel(0x0, phy->base + REG_DSI_28nm_8960_PHY_CTRL_0); + + /* + * Wait for the registers writes to complete in order to +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +index f72ce6a3c456d..8e2af844d240d 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +@@ -204,20 +204,20 @@ static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *c + if (config->enable_ssc) { + pr_debug("SSC is enabled\n"); + +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1, +- config->ssc_stepsize & 0xff); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, +- config->ssc_stepsize >> 8); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1, +- config->ssc_div_per & 0xff); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1, +- config->ssc_div_per >> 8); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1, +- config->ssc_adj_per & 0xff); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1, +- config->ssc_adj_per >> 8); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL, +- SSC_EN | (config->ssc_center ? SSC_CENTER : 0)); ++ writel(config->ssc_stepsize & 0xff, ++ base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1); ++ writel(config->ssc_stepsize >> 8, ++ base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1); ++ writel(config->ssc_div_per & 0xff, ++ base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1); ++ writel(config->ssc_div_per >> 8, ++ base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1); ++ writel(config->ssc_adj_per & 0xff, ++ base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1); ++ writel(config->ssc_adj_per >> 8, ++ base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1); ++ writel(SSC_EN | (config->ssc_center ? SSC_CENTER : 0), ++ base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL); + } + } + +@@ -252,36 +252,35 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) + vco_config_1 = 0x01; + } + +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1, +- analog_controls_five_1); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, +- !(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22); ++ writel(analog_controls_five_1, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1); ++ writel(vco_config_1, base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1); ++ writel(0x01, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE); ++ writel(0x03, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO); ++ writel(0x00, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE); ++ writel(0x00, base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER); ++ writel(0x4e, base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER); ++ writel(0x40, base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS); ++ writel(0xba, base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE); ++ writel(0x0c, base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE); ++ writel(0x00, base + REG_DSI_7nm_PHY_PLL_OUTDIV); ++ writel(0x00, base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE); ++ writel(0x08, base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO); ++ writel(0x0a, base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1); ++ writel(0xc0, base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1); ++ writel(0x84, base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1); ++ writel(0x82, base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1); ++ writel(0x4c, base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1); ++ writel(0x80, base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE); ++ writel(0x29, base + REG_DSI_7nm_PHY_PLL_PFILT); ++ writel(0x2f, base + REG_DSI_7nm_PHY_PLL_PFILT); ++ writel(0x2a, base + REG_DSI_7nm_PHY_PLL_IFILT); ++ writel(!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22, ++ base + REG_DSI_7nm_PHY_PLL_IFILT); + + if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)) { +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); ++ writel(0x22, base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE); + if (pll->slave) +- dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); ++ writel(0x22, pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE); + } + } + +@@ -289,21 +288,21 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *confi + { + void __iomem *base = pll->phy->pll_base; + +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, +- config->decimal_div_start); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, +- config->frac_div_start & 0xff); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, +- (config->frac_div_start & 0xff00) >> 8); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, +- (config->frac_div_start & 0x30000) >> 16); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, +- pll->phy->cphy_mode ? 0x00 : 0x10); +- dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, +- config->pll_clock_inverters); ++ writel(0x12, base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE); ++ writel(config->decimal_div_start, ++ base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1); ++ writel(config->frac_div_start & 0xff, ++ base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1); ++ writel((config->frac_div_start & 0xff00) >> 8, ++ base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1); ++ writel((config->frac_div_start & 0x30000) >> 16, ++ base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1); ++ writel(0x40, base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1); ++ writel(0x06, base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY); ++ writel(pll->phy->cphy_mode ? 0x00 : 0x10, ++ base + REG_DSI_7nm_PHY_PLL_CMODE_1); ++ writel(config->pll_clock_inverters, ++ base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS); + } + + static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -357,19 +356,19 @@ static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) + + static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll) + { +- u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); ++ u32 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); + +- dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0); +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5)); ++ writel(0, pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES); ++ writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); + ndelay(250); + } + + static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) + { +- u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); ++ u32 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); + +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5)); +- dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0); ++ writel(data | BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); ++ writel(0xc0, pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES); + ndelay(250); + } + +@@ -377,19 +376,18 @@ static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) + { + u32 data; + +- data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); ++ data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + } + + static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) + { + u32 data; + +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04); ++ writel(0x04, pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3); + +- data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, +- data | BIT(5) | BIT(4)); ++ data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ writel(data | BIT(5) | BIT(4), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + } + + static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) +@@ -399,9 +397,9 @@ static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) + * coming out of a CX or analog rail power collapse while + * ensuring that the pads maintain LP00 or LP11 state + */ +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); ++ writel(BIT(0), pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4); + wmb(); /* Ensure that the reset is deasserted */ +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); ++ writel(0, pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4); + wmb(); /* Ensure that the reset is deasserted */ + } + +@@ -415,7 +413,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) + dsi_pll_enable_pll_bias(pll_7nm->slave); + + /* Start PLL */ +- dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01); ++ writel(BIT(0), pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); + + /* + * ensure all PLL configurations are written prior to checking +@@ -451,7 +449,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) + + static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll) + { +- dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0); ++ writel(0, pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL); + dsi_pll_disable_pll_bias(pll); + } + +@@ -465,7 +463,7 @@ static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) + * powering down the PLL + */ + dsi_pll_disable_global_clk(pll_7nm); +- dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0); ++ writel(0, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); + dsi_pll_disable_sub(pll_7nm); + if (pll_7nm->slave) { + dsi_pll_disable_global_clk(pll_7nm->slave); +@@ -488,13 +486,13 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, + u32 dec; + u64 pll_freq, tmp64; + +- dec = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1); ++ dec = readl(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1); + dec &= 0xff; + +- frac = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1); +- frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) & ++ frac = readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1); ++ frac |= ((readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) & + 0xff) << 8); +- frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & ++ frac |= ((readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & + 0x3) << 16); + + /* +@@ -547,15 +545,15 @@ static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy) + void __iomem *phy_base = pll_7nm->phy->base; + u32 cmn_clk_cfg0, cmn_clk_cfg1; + +- cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base + ++ cached->pll_out_div = readl(pll_7nm->phy->pll_base + + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + cached->pll_out_div &= 0x3; + +- cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); ++ cmn_clk_cfg0 = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); + cached->bit_clk_div = cmn_clk_cfg0 & 0xf; + cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; + +- cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ cmn_clk_cfg1 = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + cached->pll_mux = cmn_clk_cfg1 & 0x3; + + DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", +@@ -571,18 +569,18 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy) + u32 val; + int ret; + +- val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); ++ val = readl(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + val &= ~0x3; + val |= cached->pll_out_div; +- dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val); ++ writel(val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + +- dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, +- cached->bit_clk_div | (cached->pix_clk_div << 4)); ++ writel(cached->bit_clk_div | (cached->pix_clk_div << 4), ++ phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); + +- val = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ val = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + val &= ~0x3; + val |= cached->pll_mux; +- dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val); ++ writel(val, phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + + ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, + pll_7nm->vco_current_rate, +@@ -620,7 +618,7 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) + } + + /* set PLL src */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2)); ++ writel(data << 2, base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + + return 0; + } +@@ -722,8 +720,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide + if (pll_7nm->phy->cphy_mode) { + u32 data; + +- data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); +- dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3); ++ data = readl(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); ++ writel(data | 3, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + + phy_pll_out_dsi_parent = pll_post_out_div; + } else { +@@ -802,7 +800,7 @@ static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy) + void __iomem *base = phy->base; + u32 data = 0; + +- data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); ++ data = readl(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); + mb(); /* make sure read happened */ + + return (data & BIT(0)); +@@ -818,11 +816,9 @@ static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable) + * corresponding to the logical data lane 0 + */ + if (enable) +- dsi_phy_write(lane_base + +- REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3); ++ writel(0x3, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0)); + else +- dsi_phy_write(lane_base + +- REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0); ++ writel(0, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0)); + } + + static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy) +@@ -843,18 +839,18 @@ static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy) + * be only enabled for the physical data lane corresponding + * to the logical data lane 0 + */ +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i), 0); +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i), 0x0); ++ writel(0, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i)); ++ writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i)); + } + + dsi_phy_hw_v4_0_config_lpcdrx(phy, true); + + /* other settings */ + for (i = 0; i < 5; i++) { +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG0(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG1(i), 0x0); +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG2(i), i == 4 ? 0x8a : 0xa); +- dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]); ++ writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_CFG0(i)); ++ writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_CFG1(i)); ++ writel(i == 4 ? 0x8a : 0xa, lane_base + REG_DSI_7nm_PHY_LN_CFG2(i)); ++ writel(tx_dctrl[i], lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i)); + } + } + +@@ -892,7 +888,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, + /* Request for REFGEN READY */ + if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) || + (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) { +- dsi_phy_write(phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x1); ++ writel(0x1, phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10); + udelay(500); + } + +@@ -977,53 +973,53 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, + + /* de-assert digital and pll power down */ + data = BIT(6) | BIT(5); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data); ++ writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0); + + /* Assert PLL core reset */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x00); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); + + /* turn off resync FIFO */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL); + + /* program CMN_CTRL_4 for minor_ver 2 chipsets*/ + if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) || +- (dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20) +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04); ++ (readl(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20) ++ writel(0x04, base + REG_DSI_7nm_PHY_CMN_CTRL_4); + + /* Configure PHY lane swap (TODO: we need to calculate this) */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84); ++ writel(0x21, base + REG_DSI_7nm_PHY_CMN_LANE_CFG0); ++ writel(0x84, base + REG_DSI_7nm_PHY_CMN_LANE_CFG1); + + if (phy->cphy_mode) +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6)); ++ writel(BIT(6), base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL); + + /* Enable LDO */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1); +- +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL, +- glbl_str_swi_cal_sel_ctrl); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0, +- glbl_hstx_str_ctrl_0); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0, +- glbl_pemph_ctrl_0); ++ writel(vreg_ctrl_0, base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0); ++ writel(vreg_ctrl_1, base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1); ++ ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_3); ++ writel(glbl_str_swi_cal_sel_ctrl, ++ base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL); ++ writel(glbl_hstx_str_ctrl_0, ++ base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0); ++ writel(glbl_pemph_ctrl_0, ++ base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0); + if (phy->cphy_mode) +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL, +- glbl_rescode_top_ctrl); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL, +- glbl_rescode_bot_ctrl); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL, 0x55); ++ writel(0x01, base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1); ++ writel(glbl_rescode_top_ctrl, ++ base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL); ++ writel(glbl_rescode_bot_ctrl, ++ base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL); ++ writel(0x55, base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL); + + /* Remove power down from all blocks */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f); ++ writel(0x7f, base + REG_DSI_7nm_PHY_CMN_CTRL_0); + +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0); ++ writel(lane_ctrl0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0); + + /* Select full-rate mode */ + if (!phy->cphy_mode) +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40); ++ writel(0x40, base + REG_DSI_7nm_PHY_CMN_CTRL_2); + + ret = dsi_7nm_set_usecase(phy); + if (ret) { +@@ -1034,34 +1030,34 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, + + /* DSI PHY timings */ + if (phy->cphy_mode) { +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, +- timing->shared_timings.clk_pre); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, +- timing->shared_timings.clk_post); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0); ++ writel(timing->hs_exit, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4); ++ writel(timing->shared_timings.clk_pre, ++ base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5); ++ writel(timing->clk_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6); ++ writel(timing->shared_timings.clk_post, ++ base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7); ++ writel(timing->hs_rqst, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8); ++ writel(0x02, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9); ++ writel(0x04, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11); + } else { +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12, +- timing->shared_timings.clk_pre); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13, +- timing->shared_timings.clk_post); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0); ++ writel(timing->clk_zero, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1); ++ writel(timing->clk_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2); ++ writel(timing->clk_trail, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3); ++ writel(timing->hs_exit, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4); ++ writel(timing->hs_zero, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5); ++ writel(timing->hs_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6); ++ writel(timing->hs_trail, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7); ++ writel(timing->hs_rqst, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8); ++ writel(0x02, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9); ++ writel(0x04, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11); ++ writel(timing->shared_timings.clk_pre, ++ base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12); ++ writel(timing->shared_timings.clk_post, ++ base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13); + } + + /* DSI lane settings */ +@@ -1077,12 +1073,12 @@ static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable) + void __iomem *base = phy->base; + u32 data; + +- data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1); ++ data = readl(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1); + if (enable) + data |= BIT(5) | BIT(6); + else + data &= ~(BIT(5) | BIT(6)); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1, data); ++ writel(data, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1); + + return enable; + } +@@ -1102,21 +1098,21 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) + /* Turn off REFGEN Vote */ + if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) || + (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) { +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x0); ++ writel(0x0, base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10); + wmb(); + /* Delay to ensure HW removes vote before PHY shut down */ + udelay(2); + } + +- data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0); ++ data = readl(base + REG_DSI_7nm_PHY_CMN_CTRL_0); + + /* disable all lanes */ + data &= ~0x1F; +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data); +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, 0); ++ writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0); ++ writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0); + + /* Turn off all PHY blocks */ +- dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x00); ++ writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0); + /* make sure phy is turned off */ + wmb(); + +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-gem-demote-userspace-errors-to-drm_ut_driver.patch b/queue-6.6/drm-msm-gem-demote-userspace-errors-to-drm_ut_driver.patch new file mode 100644 index 0000000000..525e4a3592 --- /dev/null +++ b/queue-6.6/drm-msm-gem-demote-userspace-errors-to-drm_ut_driver.patch @@ -0,0 +1,163 @@ +From a9ad28eb1ce68329995d7890f218a1b5216bb394 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 10:08:04 -0700 +Subject: drm/msm/gem: Demote userspace errors to DRM_UT_DRIVER + +From: Rob Clark + +[ Upstream commit b2acb89af1a400be721bcb14f137aa22b509caba ] + +Error messages resulting from incorrect usage of the kernel uabi should +not spam dmesg by default. But it is useful to enable them to debug +userspace. So demote to DRM_UT_DRIVER. + +Signed-off-by: Rob Clark +Patchwork: https://patchwork.freedesktop.org/patch/564189/ +Stable-dep-of: 3a47f4b439be ("drm/msm/gem: prevent integer overflow in msm_ioctl_gem_submit()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gem.c | 6 ++--- + drivers/gpu/drm/msm/msm_gem_submit.c | 36 ++++++++++++++++------------ + 2 files changed, 24 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c +index db1e748daa753..1113e6b2ec8ec 100644 +--- a/drivers/gpu/drm/msm/msm_gem.c ++++ b/drivers/gpu/drm/msm/msm_gem.c +@@ -226,9 +226,9 @@ static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj, + + msm_gem_assert_locked(obj); + +- if (GEM_WARN_ON(msm_obj->madv > madv)) { +- DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n", +- msm_obj->madv, madv); ++ if (msm_obj->madv > madv) { ++ DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n", ++ msm_obj->madv, madv); + return ERR_PTR(-EBUSY); + } + +diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c +index 99744de6c05a1..207b6ba1565d8 100644 +--- a/drivers/gpu/drm/msm/msm_gem_submit.c ++++ b/drivers/gpu/drm/msm/msm_gem_submit.c +@@ -17,6 +17,12 @@ + #include "msm_gem.h" + #include "msm_gpu_trace.h" + ++/* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable ++ * error msgs for debugging, but we don't spam dmesg by default ++ */ ++#define SUBMIT_ERROR(submit, fmt, ...) \ ++ DRM_DEV_DEBUG_DRIVER((submit)->dev->dev, fmt, ##__VA_ARGS__) ++ + /* + * Cmdstream submission: + */ +@@ -136,7 +142,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + + if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || + !(submit_bo.flags & MANDATORY_FLAGS)) { +- DRM_ERROR("invalid flags: %x\n", submit_bo.flags); ++ SUBMIT_ERROR(submit, "invalid flags: %x\n", submit_bo.flags); + ret = -EINVAL; + i = 0; + goto out; +@@ -158,7 +164,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + */ + obj = idr_find(&file->object_idr, submit->bos[i].handle); + if (!obj) { +- DRM_ERROR("invalid handle %u at index %u\n", submit->bos[i].handle, i); ++ SUBMIT_ERROR(submit, "invalid handle %u at index %u\n", submit->bos[i].handle, i); + ret = -EINVAL; + goto out_unlock; + } +@@ -202,13 +208,13 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, + case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: + break; + default: +- DRM_ERROR("invalid type: %08x\n", submit_cmd.type); ++ SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type); + return -EINVAL; + } + + if (submit_cmd.size % 4) { +- DRM_ERROR("non-aligned cmdstream buffer size: %u\n", +- submit_cmd.size); ++ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n", ++ submit_cmd.size); + ret = -EINVAL; + goto out; + } +@@ -306,8 +312,8 @@ static int submit_lock_objects(struct msm_gem_submit *submit) + + fail: + if (ret == -EALREADY) { +- DRM_ERROR("handle %u at index %u already on submit list\n", +- submit->bos[i].handle, i); ++ SUBMIT_ERROR(submit, "handle %u at index %u already on submit list\n", ++ submit->bos[i].handle, i); + ret = -EINVAL; + } + +@@ -448,8 +454,8 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, + struct drm_gem_object **obj, uint64_t *iova, bool *valid) + { + if (idx >= submit->nr_bos) { +- DRM_ERROR("invalid buffer index: %u (out of %u)\n", +- idx, submit->nr_bos); ++ SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n", ++ idx, submit->nr_bos); + return -EINVAL; + } + +@@ -475,7 +481,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + return 0; + + if (offset % 4) { +- DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); ++ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", offset); + return -EINVAL; + } + +@@ -497,8 +503,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + bool valid; + + if (submit_reloc.submit_offset % 4) { +- DRM_ERROR("non-aligned reloc offset: %u\n", +- submit_reloc.submit_offset); ++ SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n", ++ submit_reloc.submit_offset); + ret = -EINVAL; + goto out; + } +@@ -508,7 +514,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob + + if ((off >= (obj->size / 4)) || + (off < last_offset)) { +- DRM_ERROR("invalid offset %u at reloc %u\n", off, i); ++ SUBMIT_ERROR(submit, "invalid offset %u at reloc %u\n", off, i); + ret = -EINVAL; + goto out; + } +@@ -881,7 +887,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, + if (!submit->cmd[i].size || + ((submit->cmd[i].size + submit->cmd[i].offset) > + obj->size / 4)) { +- DRM_ERROR("invalid cmdstream size: %u\n", submit->cmd[i].size * 4); ++ SUBMIT_ERROR(submit, "invalid cmdstream size: %u\n", submit->cmd[i].size * 4); + ret = -EINVAL; + goto out; + } +@@ -893,7 +899,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, + + if (!gpu->allow_relocs) { + if (submit->cmd[i].nr_relocs) { +- DRM_ERROR("relocs not allowed\n"); ++ SUBMIT_ERROR(submit, "relocs not allowed\n"); + ret = -EINVAL; + goto out; + } +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-gem-prevent-integer-overflow-in-msm_ioctl_ge.patch b/queue-6.6/drm-msm-gem-prevent-integer-overflow-in-msm_ioctl_ge.patch new file mode 100644 index 0000000000..5e64e37037 --- /dev/null +++ b/queue-6.6/drm-msm-gem-prevent-integer-overflow-in-msm_ioctl_ge.patch @@ -0,0 +1,41 @@ +From ad2ce946e7fb77599314bcf2a5e1b6b9ead8c8c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Nov 2024 17:50:08 +0300 +Subject: drm/msm/gem: prevent integer overflow in msm_ioctl_gem_submit() + +From: Dan Carpenter + +[ Upstream commit 3a47f4b439beb98e955d501c609dfd12b7836d61 ] + +The "submit->cmd[i].size" and "submit->cmd[i].offset" variables are u32 +values that come from the user via the submit_lookup_cmds() function. +This addition could lead to an integer wrapping bug so use size_add() +to prevent that. + +Fixes: 198725337ef1 ("drm/msm: fix cmdstream size check") +Cc: stable@vger.kernel.org +Signed-off-by: Dan Carpenter +Patchwork: https://patchwork.freedesktop.org/patch/624696/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gem_submit.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c +index 207b6ba1565d8..018b39546fc1d 100644 +--- a/drivers/gpu/drm/msm/msm_gem_submit.c ++++ b/drivers/gpu/drm/msm/msm_gem_submit.c +@@ -885,8 +885,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, + goto out; + + if (!submit->cmd[i].size || +- ((submit->cmd[i].size + submit->cmd[i].offset) > +- obj->size / 4)) { ++ (size_add(submit->cmd[i].size, submit->cmd[i].offset) > obj->size / 4)) { + SUBMIT_ERROR(submit, "invalid cmdstream size: %u\n", submit->cmd[i].size * 4); + ret = -EINVAL; + goto out; +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-generate-headers-on-the-fly.patch b/queue-6.6/drm-msm-generate-headers-on-the-fly.patch new file mode 100644 index 0000000000..58bda423f9 --- /dev/null +++ b/queue-6.6/drm-msm-generate-headers-on-the-fly.patch @@ -0,0 +1,208 @@ +From 033c44b0461d42697677c63d65c48d29145ee065 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:41 +0300 +Subject: drm/msm: generate headers on the fly + +From: Dmitry Baryshkov + +[ Upstream commit 0fddd045f88e34d6160785a3a5e506d374566454 ] + +Generate DRM/MSM headers on the fly during kernel build. This removes a +need to push register changes to Mesa with the following manual +synchronization step. Existing headers will be removed in the following +commits (split away to ease reviews). + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585862/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-11-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/.gitignore | 1 + + drivers/gpu/drm/msm/Makefile | 97 ++++++++++++++++++++++++++-------- + 2 files changed, 77 insertions(+), 21 deletions(-) + create mode 100644 drivers/gpu/drm/msm/.gitignore + +diff --git a/drivers/gpu/drm/msm/.gitignore b/drivers/gpu/drm/msm/.gitignore +new file mode 100644 +index 0000000000000..9ab870da897d6 +--- /dev/null ++++ b/drivers/gpu/drm/msm/.gitignore +@@ -0,0 +1 @@ ++generated/ +diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile +index 8d02d8c330695..0893f44468dd6 100644 +--- a/drivers/gpu/drm/msm/Makefile ++++ b/drivers/gpu/drm/msm/Makefile +@@ -1,10 +1,11 @@ + # SPDX-License-Identifier: GPL-2.0 + ccflags-y := -I $(srctree)/$(src) ++ccflags-y += -I $(obj)/generated + ccflags-y += -I $(srctree)/$(src)/disp/dpu1 + ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi + ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp + +-msm-y := \ ++adreno-y := \ + adreno/adreno_device.o \ + adreno/adreno_gpu.o \ + adreno/a2xx_gpu.o \ +@@ -17,7 +18,11 @@ msm-y := \ + adreno/a6xx_gmu.o \ + adreno/a6xx_hfi.o \ + +-msm-$(CONFIG_DRM_MSM_HDMI) += \ ++adreno-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ ++ ++adreno-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o ++ ++msm-display-$(CONFIG_DRM_MSM_HDMI) += \ + hdmi/hdmi.o \ + hdmi/hdmi_audio.o \ + hdmi/hdmi_bridge.o \ +@@ -30,7 +35,7 @@ msm-$(CONFIG_DRM_MSM_HDMI) += \ + hdmi/hdmi_phy_8x74.o \ + hdmi/hdmi_pll_8960.o \ + +-msm-$(CONFIG_DRM_MSM_MDP4) += \ ++msm-display-$(CONFIG_DRM_MSM_MDP4) += \ + disp/mdp4/mdp4_crtc.o \ + disp/mdp4/mdp4_dsi_encoder.o \ + disp/mdp4/mdp4_dtv_encoder.o \ +@@ -41,7 +46,7 @@ msm-$(CONFIG_DRM_MSM_MDP4) += \ + disp/mdp4/mdp4_kms.o \ + disp/mdp4/mdp4_plane.o \ + +-msm-$(CONFIG_DRM_MSM_MDP5) += \ ++msm-display-$(CONFIG_DRM_MSM_MDP5) += \ + disp/mdp5/mdp5_cfg.o \ + disp/mdp5/mdp5_cmd_encoder.o \ + disp/mdp5/mdp5_ctl.o \ +@@ -54,7 +59,7 @@ msm-$(CONFIG_DRM_MSM_MDP5) += \ + disp/mdp5/mdp5_plane.o \ + disp/mdp5/mdp5_smp.o \ + +-msm-$(CONFIG_DRM_MSM_DPU) += \ ++msm-display-$(CONFIG_DRM_MSM_DPU) += \ + disp/dpu1/dpu_core_perf.o \ + disp/dpu1/dpu_crtc.o \ + disp/dpu1/dpu_encoder.o \ +@@ -83,14 +88,16 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ + disp/dpu1/dpu_vbif.o \ + disp/dpu1/dpu_writeback.o + +-msm-$(CONFIG_DRM_MSM_MDSS) += \ ++msm-display-$(CONFIG_DRM_MSM_MDSS) += \ + msm_mdss.o \ + +-msm-y += \ ++msm-display-y += \ + disp/mdp_format.o \ + disp/mdp_kms.o \ + disp/msm_disp_snapshot.o \ + disp/msm_disp_snapshot_util.o \ ++ ++msm-y += \ + msm_atomic.o \ + msm_atomic_tracepoints.o \ + msm_debugfs.o \ +@@ -113,12 +120,12 @@ msm-y += \ + msm_gpu_tracepoints.o \ + msm_gpummu.o + +-msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ +- dp/dp_debug.o ++msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o + +-msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o ++msm-display-$(CONFIG_DEBUG_FS) += \ ++ dp/dp_debug.o + +-msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ ++msm-display-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ + dp/dp_catalog.o \ + dp/dp_ctrl.o \ + dp/dp_display.o \ +@@ -129,21 +136,69 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ + dp/dp_power.o \ + dp/dp_audio.o + +-msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o +- +-msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o ++msm-display-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o + +-msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ ++msm-display-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ + dsi/dsi_cfg.o \ + dsi/dsi_host.o \ + dsi/dsi_manager.o \ + dsi/phy/dsi_phy.o + +-msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o +-msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o +-msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o +-msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o +-msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o +-msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o ++msm-display-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o ++msm-display-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o ++msm-display-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o ++msm-display-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o ++msm-display-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o ++msm-display-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o ++ ++msm-y += $(adreno-y) $(msm-display-y) + + obj-$(CONFIG_DRM_MSM) += msm.o ++ ++quiet_cmd_headergen = GENHDR $@ ++ cmd_headergen = mkdir -p $(obj)/generated && $(PYTHON3) $(srctree)/$(src)/registers/gen_header.py --rnn $(srctree)/$(src)/registers --xml $< c-defines > $@ ++ ++$(obj)/generated/%.xml.h: $(src)/registers/adreno/%.xml \ ++ $(src)/registers/adreno/adreno_common.xml \ ++ $(src)/registers/adreno/adreno_pm4.xml \ ++ $(src)/registers/freedreno_copyright.xml \ ++ $(src)/registers/gen_header.py \ ++ $(src)/registers/rules-fd.xsd \ ++ FORCE ++ $(call if_changed,headergen) ++ ++$(obj)/generated/%.xml.h: $(src)/registers/display/%.xml \ ++ $(src)/registers/freedreno_copyright.xml \ ++ $(src)/registers/gen_header.py \ ++ $(src)/registers/rules-fd.xsd \ ++ FORCE ++ $(call if_changed,headergen) ++ ++ADRENO_HEADERS = \ ++ generated/a2xx.xml.h \ ++ generated/a3xx.xml.h \ ++ generated/a4xx.xml.h \ ++ generated/a5xx.xml.h \ ++ generated/a6xx.xml.h \ ++ generated/a6xx_gmu.xml.h \ ++ generated/adreno_common.xml.h \ ++ generated/adreno_pm4.xml.h \ ++ ++DISPLAY_HEADERS = \ ++ generated/dsi_phy_7nm.xml.h \ ++ generated/dsi_phy_10nm.xml.h \ ++ generated/dsi_phy_14nm.xml.h \ ++ generated/dsi_phy_20nm.xml.h \ ++ generated/dsi_phy_28nm_8960.xml.h \ ++ generated/dsi_phy_28nm.xml.h \ ++ generated/dsi.xml.h \ ++ generated/hdmi.xml.h \ ++ generated/mdp4.xml.h \ ++ generated/mdp5.xml.h \ ++ generated/mdp_common.xml.h \ ++ generated/sfpb.xml.h ++ ++$(addprefix $(obj)/,$(adreno-y)): $(addprefix $(obj)/,$(ADRENO_HEADERS)) ++$(addprefix $(obj)/,$(msm-display-y)): $(addprefix $(obj)/,$(DISPLAY_HEADERS)) ++ ++targets += $(ADRENO_HEADERS) $(DISPLAY_HEADERS) +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-import-a2xx-a4xx-xml-display-registers-datab.patch b/queue-6.6/drm-msm-import-a2xx-a4xx-xml-display-registers-datab.patch new file mode 100644 index 0000000000..8357c75ba5 --- /dev/null +++ b/queue-6.6/drm-msm-import-a2xx-a4xx-xml-display-registers-datab.patch @@ -0,0 +1,8756 @@ +From ddf38f66393fed30cdd24d7d6c3c9ac37a51617a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:37 +0300 +Subject: drm/msm: import A2xx-A4xx XML display registers database + +From: Dmitry Baryshkov + +[ Upstream commit ae22a94997b8a03dcb3c922857c203246711f9d4 ] + +Import Adreno registers database for A2xx-A4xx from the Mesa, commit +639488f924d9 ("freedreno/registers: limit the rules schema"). + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585854/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-7-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/registers/adreno/a2xx.xml | 1865 +++++++++++++ + drivers/gpu/drm/msm/registers/adreno/a3xx.xml | 1751 ++++++++++++ + drivers/gpu/drm/msm/registers/adreno/a4xx.xml | 2409 +++++++++++++++++ + .../msm/registers/adreno/adreno_common.xml | 400 +++ + .../drm/msm/registers/adreno/adreno_pm4.xml | 2268 ++++++++++++++++ + 5 files changed, 8693 insertions(+) + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a2xx.xml + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a3xx.xml + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a4xx.xml + create mode 100644 drivers/gpu/drm/msm/registers/adreno/adreno_common.xml + create mode 100644 drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml + +diff --git a/drivers/gpu/drm/msm/registers/adreno/a2xx.xml b/drivers/gpu/drm/msm/registers/adreno/a2xx.xml +new file mode 100644 +index 0000000000000..22caddaa0db94 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a2xx.xml +@@ -0,0 +1,1865 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ note: only 0x3f worth of valid register values for VS_REGS and ++ PS_REGS, but high bit is set to indicate '0 registers used': ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture state dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/adreno/a3xx.xml b/drivers/gpu/drm/msm/registers/adreno/a3xx.xml +new file mode 100644 +index 0000000000000..6717abc0a897b +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a3xx.xml +@@ -0,0 +1,1751 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The pair of MEM_SIZE/ADDR registers get programmed ++ in sequence with the size/addr of each buffer. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ aka clip_halfz ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ range of -8.0 to 8.0 ++ ++ ++ range of -512.0 to 512.0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ RENDER_MODE is RB_RESOLVE_PASS for gmem->mem, otherwise RB_RENDER_PASS ++ ++ ++ ++ render targets - 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch (actually, appears to be pitch in bytes, so really is a stride) ++ in GMEM, so pitch of the current tile. ++ ++ ++ ++ ++ offset into GMEM (or system memory address in bypass mode) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ actually, appears to be pitch in bytes, so really is a stride ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER ++ ++ ++ ++ seems to be always set to 0x00000000 ++ ++ ++ ++ ++ DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie ++ bin_w * bin_h / 1024 (possible rounded up to multiple of ++ something?? ie. 39 becomes 40, 78 becomes 80.. 75 becomes ++ 80.. so maybe it needs to be multiple of 8?? ++ ++ ++ ++ ++ ++ Pitch of depth buffer or combined depth+stencil buffer ++ in z24s8 cases. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be always set to 0x00000000 ++ ++ ++ Base address for stencil when not using interleaved depth/stencil ++ ++ ++ ++ pitch of stencil buffer when not using interleaved depth/stencil ++ ++ ++ ++ ++ ++ seems to be set to 0x00000002 during binning pass ++ ++ ++ ++ X/Y offset of current bin ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be where firmware writes BIN_DATA_ADDR from ++ CP_SET_BIN_DATA packet.. probably should be called ++ PC_BIN_BASE (just using name from yamato for now) ++ ++ ++ ++ probably should be PC_BIN_SIZE ++ ++ ++ SIZE is current pipe width * height (in tiles) ++ ++ ++ N is some sort of slot # between 0..(SIZE-1). In case ++ multiple tiles use same pipe, each tile gets unique slot # ++ ++ ++ ++ ++ ++ ++ STRIDE_IN_VPC: ALIGN(next_outloc - 8, 4) / 4 ++ (but, in cases where you'd expect 1, the blob driver uses ++ 2, so possibly 0 (no varying) or minimum of 2) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ indexed by dimension ++ ++ ++ ++ ++ ++ ++ ++ indexed by dimension, global_size / local_size ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ TOTALATTRTOVS is # of attributes to vertex shader, in register ++ slots (ie. vec4+vec3 -> 7) ++ ++ ++ ++ STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid ++ ++ STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid ++ ++ ++ ++ MAXSTORAGE could be # of attributes/vbo's ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ From register spec: ++ SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object ++ start offset in on chip RAM, ++ 128bit aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The full/half register footprint is in units of four components, ++ so if r0.x is used, that counts as all of r0.[xyzw] as used. ++ There are separate full/half register footprint values as the ++ full and half registers are independent (not overlapping). ++ Presumably the thread scheduler hardware allocates the full/half ++ register names from the actual physical register file and ++ handles the register renaming. ++ ++ ++ ++ ++ ++ ++ From regspec: ++ SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits. ++ If bit31 is 1, it means overflow ++ or any long shader. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ These seem to be offsets for storage of the varyings. ++ Always seems to start from 8, possibly loc 0 and 4 ++ are for gl_Position and gl_PointSize? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SP_VS_OBJ_START_REG contains pointer to the vertex shader program, ++ immediately followed by the binning shader program (although I ++ guess that is probably just re-using the same gpu buffer) ++ ++ ++ ++ ++ The size of memory that ldp/stp can address, in 128 byte increments. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The full/half register footprint is in units of four components, ++ so if r0.x is used, that counts as all of r0.[xyzw] as used. ++ There are separate full/half register footprint values as the ++ full and half registers are independent (not overlapping). ++ Presumably the thread scheduler hardware allocates the full/half ++ register names from the actual physical register file and ++ handles the register renaming. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ From regspec: ++ SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits. ++ If bit31 is 1, it means overflow ++ or any long shader. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SP_FS_OBJ_START_REG contains pointer to fragment shader program ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be one bit per scalar, '1' for flat, '0' for smooth ++ ++ ++ seems to be one bit per scalar, '1' for flat, '0' for smooth ++ ++ ++ ++ render targets - 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Configures the mapping between VSC_PIPE buffer and ++ bin, X/Y specify the bin index in the horiz/vert ++ direction (0,0 is upper left, 0,1 is leftmost bin ++ on second row, and so on). W/H specify the number ++ of bins assigned to this VSC_PIPE in the horiz/vert ++ dimension. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be set to 0x00000001 during binning pass ++ ++ ++ ++ seems to be always set to 0x00000001 ++ ++ ++ ++ ++ ++ ++ seems to be always set to 0x00000001 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be always set to 0x00000001 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ seems to be always set to 0x00000003 ++ ++ ++ seems to be always set to 0x00000001 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture sampler dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture constant dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ INDX is index of texture address(es) in MIPMAP state block ++ ++ Pitch in bytes (so actually stride) ++ ++ SWAP bit is set for BGRA instead of RGBA ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/adreno/a4xx.xml b/drivers/gpu/drm/msm/registers/adreno/a4xx.xml +new file mode 100644 +index 0000000000000..69a9f9b02bc95 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a4xx.xml +@@ -0,0 +1,2409 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch (actually, appears to be pitch in bytes, so really is a stride) ++ in GMEM, so pitch of the current tile. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ actually, appears to be pitch in bytes, so really is a stride ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER ++ ++ ++ ++ ++ ++ ++ DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie ++ bin_w * bin_h / 1024 (possible rounded up to multiple of ++ something?? ie. 39 becomes 40, 78 becomes 80.. 75 becomes ++ 80.. so maybe it needs to be multiple of 8?? ++ ++ ++ ++ ++ stride of depth/stencil buffer ++ ++ ++ ??? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Base address for stencil when not using interleaved depth/stencil ++ ++ ++ ++ pitch of stencil buffer when not using interleaved depth/stencil ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The full/half register footprint is in units of four components, ++ so if r0.x is used, that counts as all of r0.[xyzw] as used. ++ There are separate full/half register footprint values as the ++ full and half registers are independent (not overlapping). ++ Presumably the thread scheduler hardware allocates the full/half ++ register names from the actual physical register file and ++ handles the register renaming. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ These seem to be offsets for storage of the varyings. ++ Always seems to start from 8, possibly loc 0 and 4 ++ are for gl_Position and gl_PointSize? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ From register spec: ++ SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object ++ start offset in on chip RAM, ++ 128bit aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ These seem to be offsets for storage of the varyings. ++ Always seems to start from 8, possibly loc 0 and 4 ++ are for gl_Position and gl_PointSize? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ These seem to be offsets for storage of the varyings. ++ Always seems to start from 8, possibly loc 0 and 4 ++ are for gl_Position and gl_PointSize? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Configures the mapping between VSC_PIPE buffer and ++ bin, X/Y specify the bin index in the horiz/vert ++ direction (0,0 is upper left, 0,1 is leftmost bin ++ on second row, and so on). W/H specify the number ++ of bins assigned to this VSC_PIPE in the horiz/vert ++ dimension. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ TOTALATTRTOVS is # of attributes to vertex shader, in register ++ slots (ie. vec4+vec3 -> 7) ++ ++ ++ ++ BYPASSATTROVS seems to count varyings that are just directly ++ assigned from attributes (ie, "vFoo = aFoo;") ++ ++ ++ STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid ++ ++ STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid ++ ++ ++ ++ MAXSTORAGE could be # of attributes/vbo's ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SIZE is current pipe width * height (in tiles) ++ ++ ++ N is some sort of slot # between 0..(SIZE-1). In case ++ multiple tiles use same pipe, each tile gets unique slot # ++ ++ ++ ++ ++ ++ ++ in groups of 4x vec4, blob only uses values ++ 0, 1, 2, 4, 6, 8 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture sampler dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture constant dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch in bytes (so actually stride) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch in bytes (so actually stride) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/adreno/adreno_common.xml b/drivers/gpu/drm/msm/registers/adreno/adreno_common.xml +new file mode 100644 +index 0000000000000..218ec8bb966e3 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/adreno_common.xml +@@ -0,0 +1,400 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Registers in common between a2xx and a3xx ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Address mode for a5xx+ ++ ++ ++ ++ ++ ++ ++ Line mode for a5xx+ ++ Note that Bresenham lines are only supported with MSAA disabled. ++ ++ ++ ++ ++ ++ ++ ++ Blob (v615) seem to only use SAM and I wasn't able to coerce ++ it to produce any other command. ++ Probably valid for a4xx+ but not enabled or tested on anything ++ but a6xx. ++ ++ ++ Produces garbage ++ ++ ++ ++ ++ ++ ++ Causes reads from an invalid address ++ ++ Results in color being zero ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml b/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml +new file mode 100644 +index 0000000000000..cab01af55d222 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml +@@ -0,0 +1,2268 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Flushes dirty data from UCHE, and also writes a GPU timestamp to ++ the address if one is provided. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ If A6XX_RB_SAMPLE_COUNT_CONTROL.copy is true, writes OQ Z passed ++ sample counts to RB_SAMPLE_COUNT_ADDR. This writes to main ++ memory, skipping UCHE. ++ ++ ++ ++ ++ ++ Writes the GPU timestamp to the address that follows, once RB ++ access and flushes are complete. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Invalidates depth attachment data from the CCU. We assume this ++ happens in the last stage. ++ ++ ++ ++ ++ Invalidates color attachment data from the CCU. We assume this ++ happens in the last stage. ++ ++ ++ ++ ++ Flushes the small cache used by CP_EVENT_WRITE::BLIT (which, ++ along with its registers, would be better named RESOLVE). ++ ++ ++ ++ ++ Flushes depth attachment data from the CCU. We assume this ++ happens in the last stage. ++ ++ ++ ++ ++ Flushes color attachment data from the CCU. We assume this ++ happens in the last stage. ++ ++ ++ ++ ++ 2D blit to resolve GMEM to system memory (skipping CCU) at the ++ end of a render pass. Compare to CP_BLIT's BLIT_OP_SCALE for ++ more general blitting. ++ ++ ++ ++ ++ Clears based on GRAS_LRZ_CNTL configuration, could clear ++ fast-clear buffer or LRZ direction. ++ LRZ direction is stored at lrz_fc_offset + 0x200, has 1 byte which ++ could be expressed by enum: ++ CUR_DIR_DISABLED = 0x0 ++ CUR_DIR_GE = 0x1 ++ CUR_DIR_LE = 0x2 ++ CUR_DIR_UNSET = 0x3 ++ Clear of direction means setting the direction to CUR_DIR_UNSET. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Invalidates UCHE. ++ ++ ++ ++ ++ ++ ++ ++ Doesn't seem to do anything ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ initialize CP's micro-engine ++ ++ skip N 32-bit words to get to the next packet ++ ++ ++ indirect buffer dispatch. prefetch parser uses this packet ++ type to determine whether to pre-fetch the IB ++ ++ ++ ++ ++ ++ Takes the same arguments as CP_INDIRECT_BUFFER, but jumps to ++ another buffer at the same level. Must be at the end of IB, and ++ doesn't work with draw state IB's. ++ ++ ++ indirect buffer dispatch. same as IB, but init is pipelined ++ ++ ++ Waits for the IDLE state of the engine before further drawing. ++ This is pipelined, so the CP may continue. ++ ++ ++ wait until a register or memory location is a specific value ++ ++ wait until a register location is equal to a specific value ++ ++ wait until a register location is >= a specific value ++ ++ wait until a read completes ++ ++ wait until all base/size writes from an IB_PFD packet have completed ++ ++ ++ register read/modify/write ++ ++ Set binning configuration registers ++ ++ ++ reads register in chip and writes to memory ++ ++ write N 32-bit words to memory ++ ++ write CP_PROG_COUNTER value to memory ++ ++ conditional execution of a sequence of packets ++ ++ conditional write to memory or register ++ ++ ++ generate an event that creates a write to memory when completed ++ ++ ++ generate a VS|PS_done event ++ ++ generate a cache flush done event ++ ++ generate a z_pass done event ++ ++ ++ not sure the real name, but this seems to be what is used for ++ opencl, instead of CP_DRAW_INDX.. ++ ++ ++ initiate fetch of index buffer and draw ++ ++ draw using supplied indices in packet ++ ++ initiate fetch of index buffer and binIDs and draw ++ ++ initiate fetch of bin IDs and draw using supplied indices ++ ++ begin/end initiator for viz query extent processing ++ ++ fetch state sub-blocks and initiate shader code DMAs ++ ++ load constant into chip and to memory ++ ++ load sequencer instruction memory (pointer-based) ++ ++ load sequencer instruction memory (code embedded in packet) ++ ++ load constants from a location in memory ++ ++ selective invalidation of state pointers ++ ++ dynamically changes shader instruction memory partition ++ ++ sets the 64-bit BIN_MASK register in the PFP ++ ++ sets the 64-bit BIN_SELECT register in the PFP ++ ++ updates the current context, if needed ++ ++ generate interrupt from the command stream ++ ++ copy sequencer instruction memory to system memory ++ ++ ++ ++ ++ ++ ++ ++ sets draw initiator flags register in PFP, gets bitwise-ORed into ++ every draw initiator ++ ++ ++ sets the register protection mode ++ ++ ++ ++ ++ ++ load high level sequencer command ++ ++ ++ Conditionally load a IB based on a flag, prefetch enabled ++ ++ Conditionally load a IB based on a flag, prefetch disabled ++ ++ Load a buffer with pre-fetch enabled ++ ++ Set bin (?) ++ ++ ++ test 2 memory locations to dword values specified ++ ++ ++ Write register, ignoring context state for context sensitive registers ++ ++ ++ Record the real-time when this packet is processed by PFP ++ ++ ++ ++ ++ ++ PFP waits until the FIFO between the PFP and the ME is empty ++ ++ ++ ++ ++ Used a bit like CP_SET_CONSTANT on a2xx, but can write multiple ++ groups of registers. Looks like it can be used to create state ++ objects in GPU memory, and on state change only emit pointer ++ (via CP_SET_DRAW_STATE), which should be nice for reducing CPU ++ overhead: ++ ++ (A4x) save PM4 stream pointers to execute upon a visible draw ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Enable or disable predication globally. Also resets the ++ predicate to "passing" and the local bit to enabled when ++ enabling global predication. ++ ++ ++ ++ ++ Enable or disable predication locally. Unlike globally enabling ++ predication, this packet doesn't touch any other state. ++ Predication only happens when enabled globally and locally and a ++ predicate has been set. This should be used for internal draws ++ which aren't supposed to use the predication state: ++ ++ CP_DRAW_PRED_ENABLE_LOCAL(0) ++ ... do draw... ++ CP_DRAW_PRED_ENABLE_LOCAL(1) ++ ++ ++ ++ ++ Latch a draw predicate into the internal register. ++ ++ ++ ++ ++ for A4xx ++ Write to register with address that does not fit into type-0 pkt ++ ++ ++ ++ copy from ME scratch RAM to a register ++ ++ ++ Copy from REG to ME scratch RAM ++ ++ ++ Wait for memory writes to complete ++ ++ ++ Conditional execution based on register comparison ++ ++ ++ Memory to REG copy ++ ++ ++ ++ ++ ++ ++ for a5xx ++ ++ ++ ++ ++ ++ Tells CP the current mode of GPU operation ++ ++ Instruct CP to set a few internal CP registers ++ ++ ++ ++ ++ ++ ++ Enables IB2 skipping. If both GLOBAL and LOCAL are 1 and ++ nothing is left in the visibility stream, then ++ CP_INDIRECT_BUFFER will be skipped, and draws will early return ++ from their IB. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ General purpose 2D blit engine for image transfers and mipmap ++ generation. Reads through UCHE, writes through the CCU cache in ++ the PS stage. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Write CP_CONTEXT_SWITCH_*_INFO from CP to the following dwords, ++ and forcibly switch to the indicated context. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ These first appear in a650_sqe.bin. They can in theory be used ++ to loop any sequence of IB1 commands, but in practice they are ++ used to loop over bins. There is a fixed-size per-iteration ++ prefix, used to set per-bin state, and then the following IB1 ++ commands are executed until CP_END_BIN which are always the same ++ for each iteration and usually contain a list of ++ CP_INDIRECT_BUFFER calls to IB2 commands which setup state and ++ execute restore/draw/save commands. This replaces the previous ++ technique of just repeating the CP_INDIRECT_BUFFER calls and ++ "unrolling" the loop. ++ ++ ++ ++ ++ Make next dword 1 to disable preemption, 0 to re-enable it. ++ ++ ++ ++ ++ ++ ++ ++ ++ Can clear BV/BR counters, or wait until one catches up to another ++ ++ Clears, adds to local, or adds to global timestamp ++ ++ ++ ++ ++ Write to a scratch memory that is read by CP_REG_TEST with ++ SOURCE_SCRATCH_MEM set. It's not the same scratch as scratch registers. ++ However it uses the same memory space. ++ ++ ++ ++ ++ Executes an array of fixed-size command buffers where each ++ buffer is assumed to have one draw call, skipping buffers with ++ non-visible draw calls. ++ ++ ++ ++ Reset various on-chip state used for synchronization ++ ++ ++ ++ ++ ++ Load state, a3xx (and later?) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ inline with the CP_LOAD_STATE packet ++ ++ ++ ++ ++ in buffer pointed to by EXT_SRC_ADDR ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Load state, a4xx+ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Load state, a6xx+ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ SS6_UBO used by the a6xx vulkan blob with tesselation constants ++ in this case, EXT_SRC_ADDR is (ubo_id shl 16 | offset) ++ to load constants from a UBO loaded with DST_OFF = 14 and offset 0, ++ EXT_SRC_ADDR = 0xe0000 ++ (offset is a guess, should be in bytes given that maxUniformBufferRange=64k) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ DST_OFF same as in CP_LOAD_STATE6 - vec4 VS const at this offset will ++ be updated for each draw to {draw_id, first_vertex, first_instance, 0} ++ value of 0 disables it ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Read a 64-bit value at the given address and ++ test if it equals/doesn't equal 0. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ value at offset 0 always seems to be 0x00000000.. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Like CP_SET_BIN_DATA5, but set the pointers as offsets from the ++ pointers stored in VSC_PIPE_{DATA,DATA2,SIZE}_ADDRESS. Useful ++ for Vulkan where these values aren't known when the command ++ stream is recorded. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Modifies DST_REG using two sources that can either be registers ++ or immediates. If SRC1_ADD is set, then do the following: ++ ++ $dst = (($dst & $src0) rot $rotate) + $src1 ++ ++ Otherwise: ++ ++ $dst = (($dst & $src0) rot $rotate) | $src1 ++ ++ Here "rot" means rotate left. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Like CP_REG_TO_MEM, but the memory address to write to can be ++ offsetted using either one or two registers or scratch ++ registers. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Like CP_REG_TO_MEM, but the memory address to write to can be ++ offsetted using a DWORD in memory. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Wait until a memory value is greater than or equal to the ++ reference, using signed comparison. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This uses the same internal comparison as CP_COND_WRITE, ++ but waits until the comparison is true instead. It busy-loops in ++ the CP for the given number of cycles before trying again. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Waits for REG0 to not be 0 or REG1 to not equal REF ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Tell CP the current operation mode, indicates save and restore procedure ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Set internal CP registers, used to indicate context save data addresses ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Tests bit in specified register and sets predicate for CP_COND_REG_EXEC. ++ So: ++ ++ opcode: CP_REG_TEST (39) (2 dwords) ++ { REG = 0xc10 | BIT = 0 } ++ 0000: 70b90001 00000c10 ++ opcode: CP_COND_REG_EXEC (47) (3 dwords) ++ 0000: 70c70002 10000000 00000004 ++ opcode: CP_INDIRECT_BUFFER (3f) (4 dwords) ++ ++ Will execute the CP_INDIRECT_BUFFER only if b0 in the register at ++ offset 0x0c10 is 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Executes the following DWORDs of commands if the dword at ADDR0 ++ is not equal to 0 and the dword at ADDR1 is less than REF ++ (signed comparison). ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Used by the userspace driver to set various IB's which are ++ executed during context save/restore for handling ++ state that isn't restored by the ++ context switch routine itself. ++ ++ ++ ++ Executed unconditionally when switching back to the context. ++ ++ ++ ++ Executed when switching back after switching ++ away during execution of ++ a CP_SET_MARKER packet with RM6_YIELD as the ++ payload *and* the normal save routine was ++ bypassed for a shorter one. I think this is ++ connected to the "skipsaverestore" bit set by ++ the kernel when preempting. ++ ++ ++ ++ ++ Executed when switching away from the context, ++ except for context switches initiated via ++ CP_YIELD. ++ ++ ++ ++ ++ This can only be set by the RB (i.e. the kernel) ++ and executes with protected mode off, but ++ is otherwise similar to SAVE_IB. ++ ++ Note, kgsl calls this CP_KMD_AMBLE_TYPE ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Keep shadow copies of these registers and only set them ++ when drawing, avoiding redundant writes: ++ - VPC_CNTL_0 ++ - HLSQ_CONTROL_1_REG ++ - HLSQ_UNKNOWN_B980 ++ ++ ++ ++ Track RB_RENDER_CNTL, and insert a WFI in the following ++ situation: ++ - There is a write that disables binning ++ - There was a draw with binning left enabled, but in ++ BYPASS mode ++ Presumably this is a hang workaround? ++ ++ ++ ++ Do a mysterious CP_EVENT_WRITE 0x3f when the low bit of ++ the data to write is 0. Used by the Vulkan blob with ++ PC_MULTIVIEW_CNTL, but this isn't predicated on particular ++ register(s) like the others. ++ ++ ++ ++ Tracks GRAS_LRZ_CNTL::GREATER, GRAS_LRZ_CNTL::DIR, and ++ GRAS_LRZ_DEPTH_VIEW with previous values, and if one of ++ the following is true: ++ - GRAS_LRZ_CNTL::GREATER has changed ++ - GRAS_LRZ_CNTL::DIR has changed, the old value is not ++ CUR_DIR_GE, and the new value is not CUR_DIR_DISABLED ++ - GRAS_LRZ_DEPTH_VIEW has changed ++ then it does a LRZ_FLUSH with GRAS_LRZ_CNTL::ENABLE ++ forced to 1. ++ Only exists in a650_sqe.fw. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Note that the SMMU's definition of TTBRn can take different forms ++ depending on the pgtable format. But a5xx+ only uses aarch64 ++ format. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Unused, does not apply to aarch64 pgtable format ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Size of prefix for each bin. For each bin index i, the ++ prefix commands at PREFIX_ADDR + i * PREFIX_DWORDS are ++ executed in an IB2 before the IB1 commands following ++ this packet. ++ ++ ++ ++ Number of dwords after this packet until CP_END_BIN ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Best guess is that it is a faster way to fetch all the VSC_STATE registers ++ and keep them in a local scratch memory instead of fetching every time ++ when skipping IBs. ++ ++ ++ ++ ++ ++ Scratch memory size is 48 dwords` ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-import-a5xx-xml-display-registers-database.patch b/queue-6.6/drm-msm-import-a5xx-xml-display-registers-database.patch new file mode 100644 index 0000000000..edb056241f --- /dev/null +++ b/queue-6.6/drm-msm-import-a5xx-xml-display-registers-database.patch @@ -0,0 +1,3070 @@ +From a0dc6ebe3754f120900255f134f1f5ed7af686ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:38 +0300 +Subject: drm/msm: import A5xx XML display registers database + +From: Dmitry Baryshkov + +[ Upstream commit 2033659c22132695f6e4a70570c330e735164e55 ] + +Import Adreno registers database for A5xx from the Mesa, commit +639488f924d9 ("freedreno/registers: limit the rules schema"). + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585857/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-8-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/registers/adreno/a5xx.xml | 3039 +++++++++++++++++ + 1 file changed, 3039 insertions(+) + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a5xx.xml + +diff --git a/drivers/gpu/drm/msm/registers/adreno/a5xx.xml b/drivers/gpu/drm/msm/registers/adreno/a5xx.xml +new file mode 100644 +index 0000000000000..bd8df59451664 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a5xx.xml +@@ -0,0 +1,3039 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Configures the mapping between VSC_PIPE buffer and ++ bin, X/Y specify the bin index in the horiz/vert ++ direction (0,0 is upper left, 0,1 is leftmost bin ++ on second row, and so on). W/H specify the number ++ of bins assigned to this VSC_PIPE in the horiz/vert ++ dimension. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ LRZ: (Low Resolution Z ??) ++ ---- ++ ++ I think it serves two functions, early discard of primitives in binning ++ pass without needing full resolution depth buffer, and also functions as ++ a depth-prepass, used during the GMEM draws to discard primitives that ++ would not be visible due to later draws. ++ ++ The LRZ buffer always seems to be z16 format, regardless of actual ++ depth buffer format. ++ ++ Note that LRZ write should be disabled when blend/stencil/etc is enabled, ++ since the occluded primitive can still contribute to final color value ++ of a fragment. ++ ++ Only enabled for GL_LESS/GL_LEQUAL/GL_GREATER/GL_GEQUAL? ++ ++ ++ ++ LRZ write also disabled for blend/etc. ++ ++ update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL ++ ++ ++ ++ ++ ++ ++ ++ Pitch is depth width (in pixels) / 8 (aligned to 32). Height ++ is also divided by 8 (ie. covers 8x8 pixels) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER ++ ++ ++ ++ ++ ++ ++ ++ ++ stride of depth/stencil buffer ++ ++ ++ size of layer ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Blits: ++ ------ ++ ++ Blits are triggered by CP_EVENT_WRITE:BLIT, compared to previous ++ generations where they shared most of the gl pipeline and were ++ triggered by CP_DRAW_INDX* ++ ++ For gmem->mem blob uses RB_BLIT_CNTL.BUF to specify src of ++ blit (ie MRTn, ZS, etc) and RB_BLIT_DST_LO/HI for destination ++ gpuaddr. The gmem offset is taken from RB_MRT[n].BASE_LO/HI ++ ++ For mem->gmem blob uses just MRT0 or ZS and RB_BLIT_DST_LO/HI ++ for the GMEM offset, and gpuaddr from RB_MRT[0].BASE_LO/HI ++ (I suppose this is just to avoid trashing RB_MRT[1..7]??) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ For MASK, if RB_BLIT_CNTL.BUF=BLIT_ZS: ++ 1 - depth ++ 2 - stencil ++ 3 - depth+stencil ++ if RB_BLIT_CNTL.BUF=BLIT_MRTn ++ then probably a component mask, I always see 0xf ++ ++ ++ ++ ++ ++ Buffer Metadata (flag buffers): ++ ------------------------------- ++ ++ Blob seems to stick some metadata at the front of the buffer, ++ both z/s and MRT. I think this is same as UBWC (bandwidth ++ compression) metadata that mdp 1.7 and later supports. See ++ 1d3fae5698ce5358caab87a15383b690941697e8 in downstream kernel. ++ UBWC seems to stand for "universal bandwidth compression". ++ ++ Before glReadPixels() it does a pair of BYPASS blits (at least ++ if metadata is used) presumably to resolve metadata. ++ ++ NOTES: see: getUBwcBlockSize(), getUBwcMetaBufferSize() at ++ https://android.googlesource.com/platform/hardware/qcom/display/+/android-6.0.1_r40/msm8994/libgralloc/alloc_controller.cpp ++ (note that bpp in bytes, not bits, so really cpp) ++ ++ Example Layout 2d w/ mipmap levels: ++ ++ 100x2000, ifmt=GL_RG, fmt=GL_RG16F, type=GL_FLOAT, meta=64x512@0x8000 (7x500) ++ base=c072e000, offset=16384, size=1703936 ++ ++ color flags ++ 0 c073a000 c0732000 - level 0 flags is address ++ 1 c0838000 c0834000 programmed in texture state ++ 2 c0879000 c0877000 ++ 3 c089a000 c0899000 ++ 4 c08ab000 c08aa000 ++ 5 c08b4000 c08b3000 ++ 6 c08b9000 c08b8000 ++ 7 c08bc000 c08bb000 ++ 8 c08be000 c08bd000 ++ 9 c08c0000 c08bf000 ++ 10 c08c2000 c08c1000 ++ ++ ARRAY_PITCH is the combined size of all the levels plus flags, ++ so 0xc08c3000 - 0xc0732000 = 0x00191000 (1642496); each level ++ takes up a minimum of 2 pages (since color and flags parts are ++ each page aligned. ++ ++ { TILE_MODE = TILE5_3 | SWIZ_X = A5XX_TEX_X | SWIZ_Y = A5XX_TEX_Y | SWIZ_Z = A5XX_TEX_ZERO | SWIZ_W = A5XX_TEX_ONE | MIPLVLS = 0 | FMT = TFMT5_16_16_FLOAT | SWAP = WZYX } ++ { WIDTH = 100 | HEIGHT = 2000 } ++ { FETCHSIZE = TFETCH5_4_BYTE | PITCH = 512 | TYPE = A5XX_TEX_2D } ++ { ARRAY_PITCH = 1642496 | 0x18800000 } - NOTE c2dc always has 0x18800000 but ++ { BASE_LO = 0xc0732000 } this varies for blob gles driver.. ++ { BASE_HI = 0 | DEPTH = 1 } not sure what it is ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ num of varyings plus four for gl_Position (plus one if gl_PointSize) ++ plus # of transform-feedback (streamout) varyings if using the ++ hw streamout (rather than stg instructions in shader) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Stream-Out: ++ ----------- ++ ++ VPC_SO[0..3] registers setup details about streamout buffers, and ++ number of components to write to each. ++ ++ VPC_SO_PROG provides the mapping between output varyings and the SO ++ buffers. It is written multiple times (via a CP_CONTEXT_REG_BUNCH ++ packet, not sure if that matters), each write can handle up to two ++ components of stream-out output. Order matches up to OUTLOC, ++ including padding. So, if outputting first 3 varyings: ++ ++ SP_VS_OUT[0].REG: { A_REGID = r0.w | A_COMPMASK = 0xf | B_REGID = r0.x | B_COMPMASK = 0x7 } ++ SP_VS_OUT[0x1].REG: { A_REGID = r1.w | A_COMPMASK = 0x3 | B_REGID = r2.y | B_COMPMASK = 0xf } ++ SP_VS_VPC_DST[0].REG: { OUTLOC0 = 0 | OUTLOC1 = 4 | OUTLOC2 = 8 | OUTLOC3 = 12 } ++ ++ Then: ++ ++ VPC_SO_PROG: { A_BUF = 0 | A_OFF = 0 | A_EN | A_BUF = 0 | B_OFF = 4 | B_EN } ++ VPC_SO_PROG: { A_BUF = 0 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 12 | B_EN } ++ VPC_SO_PROG: { A_BUF = 2 | A_OFF = 0 | A_EN | A_BUF = 2 | B_OFF = 4 | B_EN } ++ VPC_SO_PROG: { A_BUF = 2 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 0 } ++ VPC_SO_PROG: { A_BUF = 1 | A_OFF = 0 | A_EN | A_BUF = 1 | B_OFF = 4 | B_EN } ++ ++ Note that varying order is OUTLOC0, OUTLOC2, OUTLOC1, and note ++ the padding between OUTLOC1 and OUTLOC2. ++ ++ The BUF bitfield indicates which of the four streamout buffers ++ to write into at the specified offset. ++ ++ The VPC_SO[n].FLUSH_BASE_LO/HI is used for hw to write back next ++ offset which gets loaded back into VPC_SO[n].BUFFER_OFFSET via a ++ CP_MEM_TO_REG. Probably can be ignored until we have GS/etc, at ++ which point we can't calculate the offset on the CPU. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The size of memory that ldp/stp can address. ++ ++ ++ ++ Guessing that this is the same as a3xx/a6xx. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ per MRT ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture sampler dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture constant dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch in bytes (so actually stride) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Pitch in bytes (so actually stride) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-import-a6xx-xml-display-registers-database.patch b/queue-6.6/drm-msm-import-a6xx-xml-display-registers-database.patch new file mode 100644 index 0000000000..edce44ee30 --- /dev/null +++ b/queue-6.6/drm-msm-import-a6xx-xml-display-registers-database.patch @@ -0,0 +1,5237 @@ +From 615167bebc153937487be2a8108f51378f1863ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:39 +0300 +Subject: drm/msm: import A6xx XML display registers database + +From: Dmitry Baryshkov + +[ Upstream commit 9cd078bbe52f8d96a224e7c9631d614407f3b338 ] + +Import Adreno registers database for A6xx from the Mesa, commit +639488f924d9 ("freedreno/registers: limit the rules schema"). + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585856/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-9-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 4970 +++++++++++++++++ + .../gpu/drm/msm/registers/adreno/a6xx_gmu.xml | 228 + + 2 files changed, 5198 insertions(+) + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a6xx.xml + create mode 100644 drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml + +diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml +new file mode 100644 +index 0000000000000..78524aaab9d4a +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml +@@ -0,0 +1,4970 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Allow early z-test and early-lrz (if applicable) ++ ++ Disable early z-test and early-lrz test (if applicable) ++ ++ ++ A special mode that allows early-lrz test but disables ++ early-z test. Which might sound a bit funny, since ++ lrz-test happens before z-test. But as long as a couple ++ conditions are maintained this allows using lrz-test in ++ cases where fragment shader has kill/discard: ++ ++ 1) Disable lrz-write in cases where it is uncertain during ++ binning pass that a fragment will pass. Ie. if frag ++ shader has-kill, writes-z, or alpha/stencil test is ++ enabled. (For correctness, lrz-write must be disabled ++ when blend is enabled.) This is analogous to how a ++ z-prepass works. ++ ++ 2) Disable lrz-write and test if a depth-test direction ++ reversal is detected. Due to condition (1), the contents ++ of the lrz buffer are a conservative estimation of the ++ depth buffer during the draw pass. Meaning that geometry ++ that we know for certain will not be visible will not pass ++ lrz-test. But geometry which may be (or contributes to ++ blend) will pass the lrz-test. ++ ++ This allows us to keep early-lrz-test in cases where the frag ++ shader does not write-z (ie. we know the z-value before FS) ++ and does not have side-effects (image/ssbo writes, etc), but ++ does have kill/discard. Which turns out to be a common ++ enough case that it is useful to keep early-lrz test against ++ the conservative lrz buffer to discard fragments that we ++ know will definitely not be visible. ++ ++ ++ Not a real hw value, used internally by mesa ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ b0..7 identifies where MRB data starts (and RB data ends) ++ b8.15 identifies where VSD data starts (and MRB data ends) ++ b16..23 identifies where IB1 data starts (and RB data ends) ++ b24..31 identifies where IB2 data starts (and IB1 data ends) ++ ++ ++ ++ ++ ++ ++ ++ ++ low bits identify where CP_SET_DRAW_STATE stateobj ++ processing starts (and IB2 data ends). I'm guessing ++ b8 is part of this since (from downstream kgsl): ++ ++ /* ROQ sizes are twice as big on a640/a680 than on a630 */ ++ if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) { ++ kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140); ++ kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362C); ++ } ... ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ number of remaining dwords incl current dword being consumed? ++ ++ ++ ++ number of remaining dwords incl current dword being consumed? ++ ++ ++ ++ number of remaining dwords incl current dword being consumed? ++ ++ ++ ++ number of remaining dwords incl current dword being consumed? ++ ++ ++ ++ number of dwords that have already been read but haven't been consumed by $addr ++ ++ ++ ++ number of remaining dwords incl current dword being consumed? ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Set to true when binning, isn't changed afterwards ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Configures the mapping between VSC_PIPE buffer and ++ bin, X/Y specify the bin index in the horiz/vert ++ direction (0,0 is upper left, 0,1 is leftmost bin ++ on second row, and so on). W/H specify the number ++ of bins assigned to this VSC_PIPE in the horiz/vert ++ dimension. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Seems to be a bitmap of which tiles mapped to the VSC ++ pipe contain geometry. ++ ++ I suppose we can connect a maximum of 32 tiles to a ++ single VSC pipe. ++ ++ ++ ++ ++ ++ ++ Has the size of data written to corresponding VSC_PRIM_STRM ++ buffer. ++ ++ ++ ++ ++ ++ ++ Has the size of data written to corresponding VSC pipe, ie. ++ same thing that is written out to VSC_DRAW_STRM_SIZE_ADDRESS_LO/HI ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ In addition to FLUSH_PER_OVERLAP, guarantee that UCHE ++ and CCU don't get out of sync when fetching the previous ++ value for the current pixel. With NO_FLUSH, there's the ++ possibility that the flags for the current pixel are ++ flushed before the data or vice-versa, leading to ++ texture fetches via UCHE getting out of sync values. ++ This mode should eliminate that. It's used in bypass ++ mode for coherent blending ++ (GL_KHR_blend_equation_advanced_coherent) as well as ++ non-coherent blending. ++ ++ ++ ++ Invalidate UCHE and wait for any pending work to finish ++ if there was possibly an overlapping primitive prior to ++ the current one. This is similar to a combination of ++ GRAS_SC_CONTROL::INJECT_L2_INVALIDATE_EVENT and ++ WAIT_RB_IDLE_ALL_TRI on a3xx. It's used in GMEM mode for ++ coherent blending ++ (GL_KHR_blend_equation_advanced_coherent). ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ LRZ write also disabled for blend/etc. ++ ++ update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL ++ ++ ++ Clears the LRZ block being touched to: ++ - 0.0 if GREATER ++ - 1.0 if LESS ++ ++ ++ ++ ++ ++ ++ ++ If DISABLE_ON_WRONG_DIR enabled - write new LRZ direction into ++ buffer, in case of mismatched direction writes 0 (disables LRZ). ++ ++ ++ ++ Disable LRZ based on previous direction and the current one. ++ If DIR_WRITE is not enabled - there is no write to direction buffer. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER ++ also set when Z_BOUNDS_ENABLE is set ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ For clearing depth/stencil ++ 1 - depth ++ 2 - stencil ++ 3 - depth+stencil ++ For clearing color buffer: ++ then probably a component mask, I always see 0xf ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Swaps TESS_CW_TRIS/TESS_CCW_TRIS, and also makes ++ triangle fans and triangle strips use the D3D ++ order instead of the OpenGL order. ++ ++ ++ ++ ++ ++ ++ ++ geometry shader ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Multi-position output lets the last geometry ++ stage shader write multiple copies of ++ gl_Position. If disabled then the VS is run once ++ for each view, and ViewID is passed as a ++ register to the VS. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Packed array of a6xx_varying_interp_mode ++ ++ ++ ++ Packed array of a6xx_varying_ps_repl_mode ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ num of varyings plus four for gl_Position (plus one if gl_PointSize) ++ plus # of transform-feedback (streamout) varyings if using the ++ hw streamout (rather than stg instructions in shader) ++ ++ ++ ++ ++ ++ ++ The number of extra copies of POSITION, i.e. ++ number of views minus one when multi-position ++ output is enabled, otherwise 0. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This VPC location will be overwritten with ++ ViewID when multiview is enabled. It's used when ++ fragment shaders read ViewID. It's only ++ strictly required for multi-position output, ++ where the same VS invocation is used for all the ++ views at once, but it can be used when multi-pos ++ output is disabled too, to avoid having to pass ++ ViewID through the VS. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ num of varyings plus four for gl_Position (plus one if gl_PointSize) ++ plus # of transform-feedback (streamout) varyings if using the ++ hw streamout (rather than stg instructions in shader) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ size in vec4s of per-primitive storage for gs. TODO: not actually in VPC ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Possibly not really "initiating" the draw but the layout is similar ++ to VGT_DRAW_INITIATOR on older gens ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Written by CP_SET_VISIBILITY_OVERRIDE handler ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This is the ID of the current patch within the ++ subdraw, used to calculate the offset of the ++ patch within the HS->DS buffers. When a draw is ++ split into multiple subdraws then this differs ++ from gl_PrimitiveID on the second, third, etc. ++ subdraws. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The size of memory that ldp/stp can address. ++ ++ ++ ++ Seems to be the same as a3xx. The maximum stack ++ size in units of 4 calls, so a call depth of 7 ++ would result in a value of 2. ++ TODO: What's the actual size per call, i.e. the ++ size of the PC? a3xx docs say it's 16 bits ++ there, but the length register now takes 28 bits ++ so it's probably been bumped to 32 bits. ++ ++ ++ ++ ++ ++ ++ ++ ++ There are four indices used to compute the ++ private memory location for an access: ++ ++ - stp/ldp offset ++ - fiber id ++ - wavefront id (a swizzled version of what "getwid" returns) ++ - SP ID (the same as what "getspid" returns) ++ ++ The stride for the SP ID is always set by ++ TOTALPVTMEMSIZE. In the per-wave layout, the ++ indices are used in this order: ++ ++ - offset % 4 (offset within dword) ++ - fiber id ++ - offset / 4 ++ - wavefront id ++ - SP ID ++ ++ and the stride for the wavefront ID is ++ MEMSIZEPERITEM, multiplied by 128 (fibers per ++ wavefront). In the per-fiber layout, the indices ++ are used in this order: ++ ++ - offset ++ - fiber id % 4 ++ - wavefront id ++ - fiber id / 4 ++ - SP ID ++ ++ and the stride for the fiber id/wavefront id ++ combo is MEMSIZEPERITEM. ++ ++ Note: Accesses of more than 1 dword do not work ++ with per-fiber layout. The blob will fall back ++ to per-wave instead. ++ ++ ++ ++ ++ ++ ++ This seems to be be the equivalent of HWSTACKOFFSET in ++ a3xx. The ldp/stp offset formula above isn't affected by ++ HWSTACKSIZEPERTHREAD at all, so the HW return address ++ stack seems to be after all the normal per-SP private ++ memory. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Normally the size of the output of the last stage in ++ dwords. It should be programmed as follows: ++ ++ size less than 63 - size ++ size of 63 (?) or 64 - 63 ++ size greater than 64 - 64 ++ ++ What to program when the size is 61-63 is a guess, but ++ both the blob and ir3 align the size to 4 dword's so it ++ doesn't matter in practice. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Enable ALL helper invocations in a quad. Necessary for ++ fine derivatives and quad subgroup ops. ++ ++ ++ ++ ++ ++ ++ ++ Enable helper invocations. Enables 3 out of 4 fragments, ++ because the coarse derivatives only use half of the quad ++ and so one pixel's value is always unused. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ per MRT ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Similar to "(eq)" flag but disables helper invocations ++ after the texture prefetch. ++ ++ ++ ++ Bypass writing to regs and overwrite output with color from ++ CONSTSLOTID const regs. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Results in color being zero ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ If 0 - all 32k of shared storage is enabled, otherwise ++ (SHARED_SIZE + 1) * 1k is enabled. ++ The ldl/stl offset seems to be rewritten to 0 when it is beyond ++ this limit. This is different from ldlw/stlw, which wraps at ++ 64k (and has 36k of storage on A640 - reads between 36k-64k ++ always return 0) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This can alternatively be interpreted as a pitch shift, ie, the ++ descriptor size is 2 << N dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Specify for which components the output color should be read ++ from alias, e.g. for: ++ ++ alias.1.b32.0 r3.x, c8.x ++ alias.1.b32.0 r2.x, c4.x ++ alias.1.b32.0 r1.x, c4.x ++ alias.1.b32.0 r0.x, c0.x ++ ++ the SP_PS_ALIASED_COMPONENTS would be 0x00001111 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This register clears pending loads queued up by ++ CP_LOAD_STATE6. Each bit resets a particular kind(s) of ++ CP_LOAD_STATE6. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ This register clears pending loads queued up by ++ CP_LOAD_STATE6. Each bit resets a particular kind(s) of ++ CP_LOAD_STATE6. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Shared constants are intended to be used for Vulkan push ++ constants. When enabled, 8 vec4's are reserved in the FS ++ const pool and 16 in the geometry const pool although ++ only 8 are actually used (why?) and they are mapped to ++ c504-c511 in each stage. Both VS and FS shared consts ++ are written using ST6_CONSTANTS/SB6_IBO, so that both ++ the geometry and FS shared consts can be written at once ++ by using CP_LOAD_STATE6 rather than ++ CP_LOAD_STATE6_FRAG/CP_LOAD_STATE6_GEOM. In addition ++ DST_OFF and NUM_UNIT are in units of dwords instead of ++ vec4's. ++ ++ There is also a separate shared constant pool for CS, ++ which is loaded through CP_LOAD_STATE6_FRAG with ++ ST6_UBO/ST6_IBO. However the only real difference for CS ++ is the dword units. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture sampler dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ clamp result to [0, 1] if the format is unorm or ++ [-1, 1] if the format is snorm, *after* ++ filtering. Has no effect for other formats. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Texture constant dwords ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ probably for D3D structured UAVs, normally set to 1 ++ ++ ++ ++ ++ ++ Pitch in bytes (so actually stride) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml +new file mode 100644 +index 0000000000000..6531749d30f4e +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml +@@ -0,0 +1,228 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-import-gen_header.py-script-from-mesa.patch b/queue-6.6/drm-msm-import-gen_header.py-script-from-mesa.patch new file mode 100644 index 0000000000..2e8a68db46 --- /dev/null +++ b/queue-6.6/drm-msm-import-gen_header.py-script-from-mesa.patch @@ -0,0 +1,993 @@ +From 0a6417c7664e2a0656c9a009deaaa9da71ba60be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:40 +0300 +Subject: drm/msm: import gen_header.py script from Mesa + +From: Dmitry Baryshkov + +[ Upstream commit 5acf49119630a463b4f6daa4b96344f87453d46d ] + +Import the gen_headers.py script from Mesa, commit b5414e716684 +("freedreno/registers: Add license header"). This script will be used to +generate MSM register files on the fly during compilation. + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585864/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-10-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/registers/gen_header.py | 961 ++++++++++++++++++++ + 1 file changed, 961 insertions(+) + create mode 100644 drivers/gpu/drm/msm/registers/gen_header.py + +diff --git a/drivers/gpu/drm/msm/registers/gen_header.py b/drivers/gpu/drm/msm/registers/gen_header.py +new file mode 100644 +index 0000000000000..9b2842d4a354f +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/gen_header.py +@@ -0,0 +1,961 @@ ++#!/usr/bin/python3 ++# ++# Copyright © 2019-2024 Google, Inc. ++# ++# SPDX-License-Identifier: MIT ++ ++import xml.parsers.expat ++import sys ++import os ++import collections ++import argparse ++import time ++import datetime ++ ++class Error(Exception): ++ def __init__(self, message): ++ self.message = message ++ ++class Enum(object): ++ def __init__(self, name): ++ self.name = name ++ self.values = [] ++ ++ def has_name(self, name): ++ for (n, value) in self.values: ++ if n == name: ++ return True ++ return False ++ ++ def names(self): ++ return [n for (n, value) in self.values] ++ ++ def dump(self): ++ use_hex = False ++ for (name, value) in self.values: ++ if value > 0x1000: ++ use_hex = True ++ ++ print("enum %s {" % self.name) ++ for (name, value) in self.values: ++ if use_hex: ++ print("\t%s = 0x%08x," % (name, value)) ++ else: ++ print("\t%s = %d," % (name, value)) ++ print("};\n") ++ ++ def dump_pack_struct(self): ++ pass ++ ++class Field(object): ++ def __init__(self, name, low, high, shr, type, parser): ++ self.name = name ++ self.low = low ++ self.high = high ++ self.shr = shr ++ self.type = type ++ ++ builtin_types = [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ] ++ ++ maxpos = parser.current_bitsize - 1 ++ ++ if low < 0 or low > maxpos: ++ raise parser.error("low attribute out of range: %d" % low) ++ if high < 0 or high > maxpos: ++ raise parser.error("high attribute out of range: %d" % high) ++ if high < low: ++ raise parser.error("low is greater than high: low=%d, high=%d" % (low, high)) ++ if self.type == "boolean" and not low == high: ++ raise parser.error("booleans should be 1 bit fields") ++ elif self.type == "float" and not (high - low == 31 or high - low == 15): ++ raise parser.error("floats should be 16 or 32 bit fields") ++ elif not self.type in builtin_types and not self.type in parser.enums: ++ raise parser.error("unknown type '%s'" % self.type) ++ ++ def ctype(self, var_name): ++ if self.type == None: ++ type = "uint32_t" ++ val = var_name ++ elif self.type == "boolean": ++ type = "bool" ++ val = var_name ++ elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid": ++ type = "uint32_t" ++ val = var_name ++ elif self.type == "int": ++ type = "int32_t" ++ val = var_name ++ elif self.type == "fixed": ++ type = "float" ++ val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix) ++ elif self.type == "ufixed": ++ type = "float" ++ val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix) ++ elif self.type == "float" and self.high - self.low == 31: ++ type = "float" ++ val = "fui(%s)" % var_name ++ elif self.type == "float" and self.high - self.low == 15: ++ type = "float" ++ val = "_mesa_float_to_half(%s)" % var_name ++ elif self.type in [ "address", "waddress" ]: ++ type = "uint64_t" ++ val = var_name ++ else: ++ type = "enum %s" % self.type ++ val = var_name ++ ++ if self.shr > 0: ++ val = "(%s >> %d)" % (val, self.shr) ++ ++ return (type, val) ++ ++def tab_to(name, value): ++ tab_count = (68 - (len(name) & ~7)) // 8 ++ if tab_count <= 0: ++ tab_count = 1 ++ print(name + ('\t' * tab_count) + value) ++ ++def mask(low, high): ++ return ((0xffffffffffffffff >> (64 - (high + 1 - low))) << low) ++ ++def field_name(reg, f): ++ if f.name: ++ name = f.name.lower() ++ else: ++ # We hit this path when a reg is defined with no bitset fields, ie. ++ # ++ name = reg.name.lower() ++ ++ if (name in [ "double", "float", "int" ]) or not (name[0].isalpha()): ++ name = "_" + name ++ ++ return name ++ ++# indices - array of (ctype, stride, __offsets_NAME) ++def indices_varlist(indices): ++ return ", ".join(["i%d" % i for i in range(len(indices))]) ++ ++def indices_prototype(indices): ++ return ", ".join(["%s i%d" % (ctype, idx) ++ for (idx, (ctype, stride, offset)) in enumerate(indices)]) ++ ++def indices_strides(indices): ++ return " + ".join(["0x%x*i%d" % (stride, idx) ++ if stride else ++ "%s(i%d)" % (offset, idx) ++ for (idx, (ctype, stride, offset)) in enumerate(indices)]) ++ ++class Bitset(object): ++ def __init__(self, name, template): ++ self.name = name ++ self.inline = False ++ if template: ++ self.fields = template.fields[:] ++ else: ++ self.fields = [] ++ ++ # Get address field if there is one in the bitset, else return None: ++ def get_address_field(self): ++ for f in self.fields: ++ if f.type in [ "address", "waddress" ]: ++ return f ++ return None ++ ++ def dump_regpair_builder(self, reg): ++ print("#ifndef NDEBUG") ++ known_mask = 0 ++ for f in self.fields: ++ known_mask |= mask(f.low, f.high) ++ if f.type in [ "boolean", "address", "waddress" ]: ++ continue ++ type, val = f.ctype("fields.%s" % field_name(reg, f)) ++ print(" assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low))) ++ print(" assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask)) ++ print("#endif\n") ++ ++ print(" return (struct fd_reg_pair) {") ++ if reg.array: ++ print(" .reg = REG_%s(__i)," % reg.full_name) ++ else: ++ print(" .reg = REG_%s," % reg.full_name) ++ ++ print(" .value =") ++ for f in self.fields: ++ if f.type in [ "address", "waddress" ]: ++ continue ++ else: ++ type, val = f.ctype("fields.%s" % field_name(reg, f)) ++ print(" (%-40s << %2d) |" % (val, f.low)) ++ value_name = "dword" ++ if reg.bit_size == 64: ++ value_name = "qword" ++ print(" fields.unknown | fields.%s," % (value_name,)) ++ ++ address = self.get_address_field() ++ if address: ++ print(" .bo = fields.bo,") ++ print(" .is_address = true,") ++ if f.type == "waddress": ++ print(" .bo_write = true,") ++ print(" .bo_offset = fields.bo_offset,") ++ print(" .bo_shift = %d," % address.shr) ++ print(" .bo_low = %d," % address.low) ++ ++ print(" };") ++ ++ def dump_pack_struct(self, reg=None): ++ if not reg: ++ return ++ ++ prefix = reg.full_name ++ ++ print("struct %s {" % prefix) ++ for f in self.fields: ++ if f.type in [ "address", "waddress" ]: ++ tab_to(" __bo_type", "bo;") ++ tab_to(" uint32_t", "bo_offset;") ++ continue ++ name = field_name(reg, f) ++ ++ type, val = f.ctype("var") ++ ++ tab_to(" %s" % type, "%s;" % name) ++ if reg.bit_size == 64: ++ tab_to(" uint64_t", "unknown;") ++ tab_to(" uint64_t", "qword;") ++ else: ++ tab_to(" uint32_t", "unknown;") ++ tab_to(" uint32_t", "dword;") ++ print("};\n") ++ ++ if reg.array: ++ print("static inline struct fd_reg_pair\npack_%s(uint32_t __i, struct %s fields)\n{" % ++ (prefix, prefix)) ++ else: ++ print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" % ++ (prefix, prefix)) ++ ++ self.dump_regpair_builder(reg) ++ ++ print("\n}\n") ++ ++ if self.get_address_field(): ++ skip = ", { .reg = 0 }" ++ else: ++ skip = "" ++ ++ if reg.array: ++ print("#define %s(__i, ...) pack_%s(__i, __struct_cast(%s) { __VA_ARGS__ })%s\n" % ++ (prefix, prefix, prefix, skip)) ++ else: ++ print("#define %s(...) pack_%s(__struct_cast(%s) { __VA_ARGS__ })%s\n" % ++ (prefix, prefix, prefix, skip)) ++ ++ ++ def dump(self, prefix=None): ++ if prefix == None: ++ prefix = self.name ++ for f in self.fields: ++ if f.name: ++ name = prefix + "_" + f.name ++ else: ++ name = prefix ++ ++ if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float", "fixed", "ufixed"]: ++ pass ++ elif f.type == "boolean" or (f.type == None and f.low == f.high): ++ tab_to("#define %s" % name, "0x%08x" % (1 << f.low)) ++ else: ++ tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high)) ++ tab_to("#define %s__SHIFT" % name, "%d" % f.low) ++ type, val = f.ctype("val") ++ ++ print("static inline uint32_t %s(%s val)\n{" % (name, type)) ++ if f.shr > 0: ++ print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1)) ++ print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name)) ++ print() ++ ++class Array(object): ++ def __init__(self, attrs, domain, variant, parent, index_type): ++ if "name" in attrs: ++ self.local_name = attrs["name"] ++ else: ++ self.local_name = "" ++ self.domain = domain ++ self.variant = variant ++ self.parent = parent ++ if self.parent: ++ self.name = self.parent.name + "_" + self.local_name ++ else: ++ self.name = self.local_name ++ if "offsets" in attrs: ++ self.offsets = map(lambda i: "0x%08x" % int(i, 0), attrs["offsets"].split(",")) ++ self.fixed_offsets = True ++ elif "doffsets" in attrs: ++ self.offsets = map(lambda s: "(%s)" % s , attrs["doffsets"].split(",")) ++ self.fixed_offsets = True ++ else: ++ self.offset = int(attrs["offset"], 0) ++ self.stride = int(attrs["stride"], 0) ++ self.fixed_offsets = False ++ if "index" in attrs: ++ self.index_type = index_type ++ else: ++ self.index_type = None ++ self.length = int(attrs["length"], 0) ++ if "usage" in attrs: ++ self.usages = attrs["usage"].split(',') ++ else: ++ self.usages = None ++ ++ def index_ctype(self): ++ if not self.index_type: ++ return "uint32_t" ++ else: ++ return "enum %s" % self.index_type.name ++ ++ # Generate array of (ctype, stride, __offsets_NAME) ++ def indices(self): ++ if self.parent: ++ indices = self.parent.indices() ++ else: ++ indices = [] ++ if self.length != 1: ++ if self.fixed_offsets: ++ indices.append((self.index_ctype(), None, f"__offset_{self.local_name}")) ++ else: ++ indices.append((self.index_ctype(), self.stride, None)) ++ return indices ++ ++ def total_offset(self): ++ offset = 0 ++ if not self.fixed_offsets: ++ offset += self.offset ++ if self.parent: ++ offset += self.parent.total_offset() ++ return offset ++ ++ def dump(self): ++ proto = indices_varlist(self.indices()) ++ strides = indices_strides(self.indices()) ++ array_offset = self.total_offset() ++ if self.fixed_offsets: ++ print("static inline uint32_t __offset_%s(%s idx)" % (self.local_name, self.index_ctype())) ++ print("{\n\tswitch (idx) {") ++ if self.index_type: ++ for val, offset in zip(self.index_type.names(), self.offsets): ++ print("\t\tcase %s: return %s;" % (val, offset)) ++ else: ++ for idx, offset in enumerate(self.offsets): ++ print("\t\tcase %d: return %s;" % (idx, offset)) ++ print("\t\tdefault: return INVALID_IDX(idx);") ++ print("\t}\n}") ++ if proto == '': ++ tab_to("#define REG_%s_%s" % (self.domain, self.name), "0x%08x\n" % array_offset) ++ else: ++ tab_to("#define REG_%s_%s(%s)" % (self.domain, self.name, proto), "(0x%08x + %s )\n" % (array_offset, strides)) ++ ++ def dump_pack_struct(self): ++ pass ++ ++ def dump_regpair_builder(self): ++ pass ++ ++class Reg(object): ++ def __init__(self, attrs, domain, array, bit_size): ++ self.name = attrs["name"] ++ self.domain = domain ++ self.array = array ++ self.offset = int(attrs["offset"], 0) ++ self.type = None ++ self.bit_size = bit_size ++ if array: ++ self.name = array.name + "_" + self.name ++ self.full_name = self.domain + "_" + self.name ++ if "stride" in attrs: ++ self.stride = int(attrs["stride"], 0) ++ self.length = int(attrs["length"], 0) ++ else: ++ self.stride = None ++ self.length = None ++ ++ # Generate array of (ctype, stride, __offsets_NAME) ++ def indices(self): ++ if self.array: ++ indices = self.array.indices() ++ else: ++ indices = [] ++ if self.stride: ++ indices.append(("uint32_t", self.stride, None)) ++ return indices ++ ++ def total_offset(self): ++ if self.array: ++ return self.array.total_offset() + self.offset ++ else: ++ return self.offset ++ ++ def dump(self): ++ proto = indices_prototype(self.indices()) ++ strides = indices_strides(self.indices()) ++ offset = self.total_offset() ++ if proto == '': ++ tab_to("#define REG_%s" % self.full_name, "0x%08x" % offset) ++ else: ++ print("static inline uint32_t REG_%s(%s) { return 0x%08x + %s; }" % (self.full_name, proto, offset, strides)) ++ ++ if self.bitset.inline: ++ self.bitset.dump(self.full_name) ++ ++ def dump_pack_struct(self): ++ if self.bitset.inline: ++ self.bitset.dump_pack_struct(self) ++ ++ def dump_regpair_builder(self): ++ if self.bitset.inline: ++ self.bitset.dump_regpair_builder(self) ++ ++ def dump_py(self): ++ print("\tREG_%s = 0x%08x" % (self.full_name, self.offset)) ++ ++ ++class Parser(object): ++ def __init__(self): ++ self.current_array = None ++ self.current_domain = None ++ self.current_prefix = None ++ self.current_prefix_type = None ++ self.current_stripe = None ++ self.current_bitset = None ++ self.current_bitsize = 32 ++ # The varset attribute on the domain specifies the enum which ++ # specifies all possible hw variants: ++ self.current_varset = None ++ # Regs that have multiple variants.. we only generated the C++ ++ # template based struct-packers for these ++ self.variant_regs = {} ++ # Information in which contexts regs are used, to be used in ++ # debug options ++ self.usage_regs = collections.defaultdict(list) ++ self.bitsets = {} ++ self.enums = {} ++ self.variants = set() ++ self.file = [] ++ self.xml_files = [] ++ self.copyright_year = None ++ self.authors = [] ++ self.license = None ++ ++ def error(self, message): ++ parser, filename = self.stack[-1] ++ return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message)) ++ ++ def prefix(self, variant=None): ++ if self.current_prefix_type == "variant" and variant: ++ return variant ++ elif self.current_stripe: ++ return self.current_stripe + "_" + self.current_domain ++ elif self.current_prefix: ++ return self.current_prefix + "_" + self.current_domain ++ else: ++ return self.current_domain ++ ++ def parse_field(self, name, attrs): ++ try: ++ if "pos" in attrs: ++ high = low = int(attrs["pos"], 0) ++ elif "high" in attrs and "low" in attrs: ++ high = int(attrs["high"], 0) ++ low = int(attrs["low"], 0) ++ else: ++ low = 0 ++ high = self.current_bitsize - 1 ++ ++ if "type" in attrs: ++ type = attrs["type"] ++ else: ++ type = None ++ ++ if "shr" in attrs: ++ shr = int(attrs["shr"], 0) ++ else: ++ shr = 0 ++ ++ b = Field(name, low, high, shr, type, self) ++ ++ if type == "fixed" or type == "ufixed": ++ b.radix = int(attrs["radix"], 0) ++ ++ self.current_bitset.fields.append(b) ++ except ValueError as e: ++ raise self.error(e) ++ ++ def parse_varset(self, attrs): ++ # Inherit the varset from the enclosing domain if not overriden: ++ varset = self.current_varset ++ if "varset" in attrs: ++ varset = self.enums[attrs["varset"]] ++ return varset ++ ++ def parse_variants(self, attrs): ++ if not "variants" in attrs: ++ return None ++ variant = attrs["variants"].split(",")[0] ++ if "-" in variant: ++ variant = variant[:variant.index("-")] ++ ++ varset = self.parse_varset(attrs) ++ ++ assert varset.has_name(variant) ++ ++ return variant ++ ++ def add_all_variants(self, reg, attrs, parent_variant): ++ # TODO this should really handle *all* variants, including dealing ++ # with open ended ranges (ie. "A2XX,A4XX-") (we have the varset ++ # enum now to make that possible) ++ variant = self.parse_variants(attrs) ++ if not variant: ++ variant = parent_variant ++ ++ if reg.name not in self.variant_regs: ++ self.variant_regs[reg.name] = {} ++ else: ++ # All variants must be same size: ++ v = next(iter(self.variant_regs[reg.name])) ++ assert self.variant_regs[reg.name][v].bit_size == reg.bit_size ++ ++ self.variant_regs[reg.name][variant] = reg ++ ++ def add_all_usages(self, reg, usages): ++ if not usages: ++ return ++ ++ for usage in usages: ++ self.usage_regs[usage].append(reg) ++ ++ self.variants.add(reg.domain) ++ ++ def do_validate(self, schemafile): ++ try: ++ from lxml import etree ++ ++ parser, filename = self.stack[-1] ++ dirname = os.path.dirname(filename) ++ ++ # we expect this to look like schema.xsd.. I think ++ # technically it is supposed to be just a URL, but that doesn't ++ # quite match up to what we do.. Just skip over everything up to ++ # and including the first whitespace character: ++ schemafile = schemafile[schemafile.rindex(" ")+1:] ++ ++ # this is a bit cheezy, but the xml file to validate could be ++ # in a child director, ie. we don't really know where the schema ++ # file is, the way the rnn C code does. So if it doesn't exist ++ # just look one level up ++ if not os.path.exists(dirname + "/" + schemafile): ++ schemafile = "../" + schemafile ++ ++ if not os.path.exists(dirname + "/" + schemafile): ++ raise self.error("Cannot find schema for: " + filename) ++ ++ xmlschema_doc = etree.parse(dirname + "/" + schemafile) ++ xmlschema = etree.XMLSchema(xmlschema_doc) ++ ++ xml_doc = etree.parse(filename) ++ if not xmlschema.validate(xml_doc): ++ error_str = str(xmlschema.error_log.filter_from_errors()[0]) ++ raise self.error("Schema validation failed for: " + filename + "\n" + error_str) ++ except ImportError: ++ print("lxml not found, skipping validation", file=sys.stderr) ++ ++ def do_parse(self, filename): ++ filepath = os.path.abspath(filename) ++ if filepath in self.xml_files: ++ return ++ self.xml_files.append(filepath) ++ file = open(filename, "rb") ++ parser = xml.parsers.expat.ParserCreate() ++ self.stack.append((parser, filename)) ++ parser.StartElementHandler = self.start_element ++ parser.EndElementHandler = self.end_element ++ parser.CharacterDataHandler = self.character_data ++ parser.buffer_text = True ++ parser.ParseFile(file) ++ self.stack.pop() ++ file.close() ++ ++ def parse(self, rnn_path, filename): ++ self.path = rnn_path ++ self.stack = [] ++ self.do_parse(filename) ++ ++ def parse_reg(self, attrs, bit_size): ++ self.current_bitsize = bit_size ++ if "type" in attrs and attrs["type"] in self.bitsets: ++ bitset = self.bitsets[attrs["type"]] ++ if bitset.inline: ++ self.current_bitset = Bitset(attrs["name"], bitset) ++ self.current_bitset.inline = True ++ else: ++ self.current_bitset = bitset ++ else: ++ self.current_bitset = Bitset(attrs["name"], None) ++ self.current_bitset.inline = True ++ if "type" in attrs: ++ self.parse_field(None, attrs) ++ ++ variant = self.parse_variants(attrs) ++ if not variant and self.current_array: ++ variant = self.current_array.variant ++ ++ self.current_reg = Reg(attrs, self.prefix(variant), self.current_array, bit_size) ++ self.current_reg.bitset = self.current_bitset ++ ++ if len(self.stack) == 1: ++ self.file.append(self.current_reg) ++ ++ if variant is not None: ++ self.add_all_variants(self.current_reg, attrs, variant) ++ ++ usages = None ++ if "usage" in attrs: ++ usages = attrs["usage"].split(',') ++ elif self.current_array: ++ usages = self.current_array.usages ++ ++ self.add_all_usages(self.current_reg, usages) ++ ++ def start_element(self, name, attrs): ++ self.cdata = "" ++ if name == "import": ++ filename = attrs["file"] ++ self.do_parse(os.path.join(self.path, filename)) ++ elif name == "domain": ++ self.current_domain = attrs["name"] ++ if "prefix" in attrs: ++ self.current_prefix = self.parse_variants(attrs) ++ self.current_prefix_type = attrs["prefix"] ++ else: ++ self.current_prefix = None ++ self.current_prefix_type = None ++ if "varset" in attrs: ++ self.current_varset = self.enums[attrs["varset"]] ++ elif name == "stripe": ++ self.current_stripe = self.parse_variants(attrs) ++ elif name == "enum": ++ self.current_enum_value = 0 ++ self.current_enum = Enum(attrs["name"]) ++ self.enums[attrs["name"]] = self.current_enum ++ if len(self.stack) == 1: ++ self.file.append(self.current_enum) ++ elif name == "value": ++ if "value" in attrs: ++ value = int(attrs["value"], 0) ++ else: ++ value = self.current_enum_value ++ self.current_enum.values.append((attrs["name"], value)) ++ elif name == "reg32": ++ self.parse_reg(attrs, 32) ++ elif name == "reg64": ++ self.parse_reg(attrs, 64) ++ elif name == "array": ++ self.current_bitsize = 32 ++ variant = self.parse_variants(attrs) ++ index_type = self.enums[attrs["index"]] if "index" in attrs else None ++ self.current_array = Array(attrs, self.prefix(variant), variant, self.current_array, index_type) ++ if len(self.stack) == 1: ++ self.file.append(self.current_array) ++ elif name == "bitset": ++ self.current_bitset = Bitset(attrs["name"], None) ++ if "inline" in attrs and attrs["inline"] == "yes": ++ self.current_bitset.inline = True ++ self.bitsets[self.current_bitset.name] = self.current_bitset ++ if len(self.stack) == 1 and not self.current_bitset.inline: ++ self.file.append(self.current_bitset) ++ elif name == "bitfield" and self.current_bitset: ++ self.parse_field(attrs["name"], attrs) ++ elif name == "database": ++ self.do_validate(attrs["xsi:schemaLocation"]) ++ elif name == "copyright": ++ self.copyright_year = attrs["year"] ++ elif name == "author": ++ self.authors.append(attrs["name"] + " <" + attrs["email"] + "> " + attrs["name"]) ++ ++ def end_element(self, name): ++ if name == "domain": ++ self.current_domain = None ++ self.current_prefix = None ++ self.current_prefix_type = None ++ elif name == "stripe": ++ self.current_stripe = None ++ elif name == "bitset": ++ self.current_bitset = None ++ elif name == "reg32": ++ self.current_reg = None ++ elif name == "array": ++ self.current_array = self.current_array.parent ++ elif name == "enum": ++ self.current_enum = None ++ elif name == "license": ++ self.license = self.cdata ++ ++ def character_data(self, data): ++ self.cdata += data ++ ++ def dump_reg_usages(self): ++ d = collections.defaultdict(list) ++ for usage, regs in self.usage_regs.items(): ++ for reg in regs: ++ variants = self.variant_regs.get(reg.name) ++ if variants: ++ for variant, vreg in variants.items(): ++ if reg == vreg: ++ d[(usage, variant)].append(reg) ++ else: ++ for variant in self.variants: ++ d[(usage, variant)].append(reg) ++ ++ print("#ifdef __cplusplus") ++ ++ for usage, regs in self.usage_regs.items(): ++ print("template constexpr inline uint16_t %s_REGS[] = {};" % (usage.upper())) ++ ++ for (usage, variant), regs in d.items(): ++ offsets = [] ++ ++ for reg in regs: ++ if reg.array: ++ for i in range(reg.array.length): ++ offsets.append(reg.array.offset + reg.offset + i * reg.array.stride) ++ if reg.bit_size == 64: ++ offsets.append(offsets[-1] + 1) ++ else: ++ offsets.append(reg.offset) ++ if reg.bit_size == 64: ++ offsets.append(offsets[-1] + 1) ++ ++ offsets.sort() ++ ++ print("template<> constexpr inline uint16_t %s_REGS<%s>[] = {" % (usage.upper(), variant)) ++ for offset in offsets: ++ print("\t%s," % hex(offset)) ++ print("};") ++ ++ print("#endif") ++ ++ def dump(self): ++ enums = [] ++ bitsets = [] ++ regs = [] ++ for e in self.file: ++ if isinstance(e, Enum): ++ enums.append(e) ++ elif isinstance(e, Bitset): ++ bitsets.append(e) ++ else: ++ regs.append(e) ++ ++ for e in enums + bitsets + regs: ++ e.dump() ++ ++ self.dump_reg_usages() ++ ++ ++ def dump_regs_py(self): ++ regs = [] ++ for e in self.file: ++ if isinstance(e, Reg): ++ regs.append(e) ++ ++ for e in regs: ++ e.dump_py() ++ ++ ++ def dump_reg_variants(self, regname, variants): ++ # Don't bother for things that only have a single variant: ++ if len(variants) == 1: ++ return ++ print("#ifdef __cplusplus") ++ print("struct __%s {" % regname) ++ # TODO be more clever.. we should probably figure out which ++ # fields have the same type in all variants (in which they ++ # appear) and stuff everything else in a variant specific ++ # sub-structure. ++ seen_fields = [] ++ bit_size = 32 ++ array = False ++ address = None ++ for variant in variants.keys(): ++ print(" /* %s fields: */" % variant) ++ reg = variants[variant] ++ bit_size = reg.bit_size ++ array = reg.array ++ for f in reg.bitset.fields: ++ fld_name = field_name(reg, f) ++ if fld_name in seen_fields: ++ continue ++ seen_fields.append(fld_name) ++ name = fld_name.lower() ++ if f.type in [ "address", "waddress" ]: ++ if address: ++ continue ++ address = f ++ tab_to(" __bo_type", "bo;") ++ tab_to(" uint32_t", "bo_offset;") ++ continue ++ type, val = f.ctype("var") ++ tab_to(" %s" %type, "%s;" %name) ++ print(" /* fallback fields: */") ++ if bit_size == 64: ++ tab_to(" uint64_t", "unknown;") ++ tab_to(" uint64_t", "qword;") ++ else: ++ tab_to(" uint32_t", "unknown;") ++ tab_to(" uint32_t", "dword;") ++ print("};") ++ # TODO don't hardcode the varset enum name ++ varenum = "chip" ++ print("template <%s %s>" % (varenum, varenum.upper())) ++ print("static inline struct fd_reg_pair") ++ xtra = "" ++ xtravar = "" ++ if array: ++ xtra = "int __i, " ++ xtravar = "__i, " ++ print("__%s(%sstruct __%s fields) {" % (regname, xtra, regname)) ++ for variant in variants.keys(): ++ print(" if (%s == %s) {" % (varenum.upper(), variant)) ++ reg = variants[variant] ++ reg.dump_regpair_builder() ++ print(" } else") ++ print(" assert(!\"invalid variant\");") ++ print("}") ++ ++ if bit_size == 64: ++ skip = ", { .reg = 0 }" ++ else: ++ skip = "" ++ ++ print("#define %s(VARIANT, %s...) __%s(%s{__VA_ARGS__})%s" % (regname, xtravar, regname, xtravar, skip)) ++ print("#endif /* __cplusplus */") ++ ++ def dump_structs(self): ++ for e in self.file: ++ e.dump_pack_struct() ++ ++ for regname in self.variant_regs: ++ self.dump_reg_variants(regname, self.variant_regs[regname]) ++ ++ ++def dump_c(args, guard, func): ++ p = Parser() ++ ++ try: ++ p.parse(args.rnn, args.xml) ++ except Error as e: ++ print(e, file=sys.stderr) ++ exit(1) ++ ++ print("#ifndef %s\n#define %s\n" % (guard, guard)) ++ ++ print("""/* Autogenerated file, DO NOT EDIT manually! ++ ++This file was generated by the rules-ng-ng gen_header.py tool in this git repository: ++http://gitlab.freedesktop.org/mesa/mesa/ ++git clone https://gitlab.freedesktop.org/mesa/mesa.git ++ ++The rules-ng-ng source files this header was generated from are: ++""") ++ maxlen = 0 ++ for filepath in p.xml_files: ++ maxlen = max(maxlen, len(filepath)) ++ for filepath in p.xml_files: ++ pad = " " * (maxlen - len(filepath)) ++ filesize = str(os.path.getsize(filepath)) ++ filesize = " " * (7 - len(filesize)) + filesize ++ filetime = time.ctime(os.path.getmtime(filepath)) ++ print("- " + filepath + pad + " (" + filesize + " bytes, from " + filetime + ")") ++ if p.copyright_year: ++ current_year = str(datetime.date.today().year) ++ print() ++ print("Copyright (C) %s-%s by the following authors:" % (p.copyright_year, current_year)) ++ for author in p.authors: ++ print("- " + author) ++ if p.license: ++ print(p.license) ++ print("*/") ++ ++ print() ++ print("#ifdef __KERNEL__") ++ print("#include ") ++ print("#define assert(x) BUG_ON(!(x))") ++ print("#else") ++ print("#include ") ++ print("#endif") ++ print() ++ ++ print("#ifdef __cplusplus") ++ print("#define __struct_cast(X)") ++ print("#else") ++ print("#define __struct_cast(X) (struct X)") ++ print("#endif") ++ print() ++ ++ func(p) ++ ++ print("\n#endif /* %s */" % guard) ++ ++ ++def dump_c_defines(args): ++ guard = str.replace(os.path.basename(args.xml), '.', '_').upper() ++ dump_c(args, guard, lambda p: p.dump()) ++ ++ ++def dump_c_pack_structs(args): ++ guard = str.replace(os.path.basename(args.xml), '.', '_').upper() + '_STRUCTS' ++ dump_c(args, guard, lambda p: p.dump_structs()) ++ ++ ++def dump_py_defines(args): ++ p = Parser() ++ ++ try: ++ p.parse(args.rnn, args.xml) ++ except Error as e: ++ print(e, file=sys.stderr) ++ exit(1) ++ ++ file_name = os.path.splitext(os.path.basename(args.xml))[0] ++ ++ print("from enum import IntEnum") ++ print("class %sRegs(IntEnum):" % file_name.upper()) ++ ++ os.path.basename(args.xml) ++ ++ p.dump_regs_py() ++ ++ ++def main(): ++ parser = argparse.ArgumentParser() ++ parser.add_argument('--rnn', type=str, required=True) ++ parser.add_argument('--xml', type=str, required=True) ++ ++ subparsers = parser.add_subparsers(required=True) ++ ++ parser_c_defines = subparsers.add_parser('c-defines') ++ parser_c_defines.set_defaults(func=dump_c_defines) ++ ++ parser_c_pack_structs = subparsers.add_parser('c-pack-structs') ++ parser_c_pack_structs.set_defaults(func=dump_c_pack_structs) ++ ++ parser_py_defines = subparsers.add_parser('py-defines') ++ parser_py_defines.set_defaults(func=dump_py_defines) ++ ++ args = parser.parse_args() ++ args.func(args) ++ ++ ++if __name__ == '__main__': ++ main() +-- +2.39.5 + diff --git a/queue-6.6/drm-msm-import-xml-display-registers-database.patch b/queue-6.6/drm-msm-import-xml-display-registers-database.patch new file mode 100644 index 0000000000..a098ea1326 --- /dev/null +++ b/queue-6.6/drm-msm-import-xml-display-registers-database.patch @@ -0,0 +1,4583 @@ +From 55c623c17f13c43e7e9d0f3c302ecb629032edd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 05:42:36 +0300 +Subject: drm/msm: import XML display registers database + +From: Dmitry Baryshkov + +[ Upstream commit 4f52f5e63b62c9db8318f435f81bcd9addcc6709 ] + +Import display-related registers database from the Mesa, commit +639488f924d9 ("freedreno/registers: limit the rules schema"). + +The msm.xml and mdp_common.xml files were adjusted to drop subdirectory paths. + +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/585852/ +Link: https://lore.kernel.org/r/20240401-fd-xml-shipped-v5-6-4bdb277a85a1@linaro.org +Stable-dep-of: 588257897058 ("drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG0 updated from driver side") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/registers/.gitignore | 4 + + drivers/gpu/drm/msm/registers/display/dsi.xml | 390 +++++++ + .../msm/registers/display/dsi_phy_10nm.xml | 102 ++ + .../msm/registers/display/dsi_phy_14nm.xml | 135 +++ + .../msm/registers/display/dsi_phy_20nm.xml | 100 ++ + .../msm/registers/display/dsi_phy_28nm.xml | 180 +++ + .../registers/display/dsi_phy_28nm_8960.xml | 134 +++ + .../drm/msm/registers/display/dsi_phy_7nm.xml | 230 ++++ + drivers/gpu/drm/msm/registers/display/edp.xml | 239 ++++ + .../gpu/drm/msm/registers/display/hdmi.xml | 1015 +++++++++++++++++ + .../gpu/drm/msm/registers/display/mdp4.xml | 504 ++++++++ + .../gpu/drm/msm/registers/display/mdp5.xml | 806 +++++++++++++ + .../drm/msm/registers/display/mdp_common.xml | 90 ++ + drivers/gpu/drm/msm/registers/display/msm.xml | 32 + + .../gpu/drm/msm/registers/display/sfpb.xml | 17 + + .../drm/msm/registers/freedreno_copyright.xml | 40 + + drivers/gpu/drm/msm/registers/rules-fd.xsd | 404 +++++++ + 17 files changed, 4422 insertions(+) + create mode 100644 drivers/gpu/drm/msm/registers/.gitignore + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/edp.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/hdmi.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/mdp4.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/mdp5.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/mdp_common.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/msm.xml + create mode 100644 drivers/gpu/drm/msm/registers/display/sfpb.xml + create mode 100644 drivers/gpu/drm/msm/registers/freedreno_copyright.xml + create mode 100644 drivers/gpu/drm/msm/registers/rules-fd.xsd + +diff --git a/drivers/gpu/drm/msm/registers/.gitignore b/drivers/gpu/drm/msm/registers/.gitignore +new file mode 100644 +index 0000000000000..848e0e3efbcb2 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/.gitignore +@@ -0,0 +1,4 @@ ++# ignore XML files present at Mesa but not used by the kernel ++adreno/adreno_control_regs.xml ++adreno/adreno_pipe_regs.xml ++adreno/ocmem.xml +diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml b/drivers/gpu/drm/msm/registers/display/dsi.xml +new file mode 100644 +index 0000000000000..501ffc585a9f6 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml +@@ -0,0 +1,390 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml +new file mode 100644 +index 0000000000000..874c3db3e1261 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml +@@ -0,0 +1,102 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml +new file mode 100644 +index 0000000000000..314b74489d49a +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml +@@ -0,0 +1,135 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml +new file mode 100644 +index 0000000000000..99e9deb361b6e +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml +@@ -0,0 +1,100 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml +new file mode 100644 +index 0000000000000..81d5b96f18c44 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml +@@ -0,0 +1,180 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml +new file mode 100644 +index 0000000000000..4c4de4dda6408 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml +@@ -0,0 +1,134 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +new file mode 100644 +index 0000000000000..d54b72f924493 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml +@@ -0,0 +1,230 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/edp.xml b/drivers/gpu/drm/msm/registers/display/edp.xml +new file mode 100644 +index 0000000000000..354f90eb6de52 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/edp.xml +@@ -0,0 +1,239 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/hdmi.xml b/drivers/gpu/drm/msm/registers/display/hdmi.xml +new file mode 100644 +index 0000000000000..6c81581016c78 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/hdmi.xml +@@ -0,0 +1,1015 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/mdp4.xml b/drivers/gpu/drm/msm/registers/display/mdp4.xml +new file mode 100644 +index 0000000000000..6abb4a3c04da9 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/mdp4.xml +@@ -0,0 +1,504 @@ ++ ++ ++ ++ ++ ++ ++ ++ pipe names, index into PIPE[] ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ appears to map pipe to mixer stage ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 8bit characters per pixel minus 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/mdp5.xml b/drivers/gpu/drm/msm/registers/display/mdp5.xml +new file mode 100644 +index 0000000000000..92f3263af1701 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/mdp5.xml +@@ -0,0 +1,806 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 8bit characters per pixel minus 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/mdp_common.xml b/drivers/gpu/drm/msm/registers/display/mdp_common.xml +new file mode 100644 +index 0000000000000..f1b6345c13235 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/mdp_common.xml +@@ -0,0 +1,90 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ bits per component (non-alpha channel) ++ ++ ++ ++ ++ ++ ++ ++ bits per component (alpha channel) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/msm.xml b/drivers/gpu/drm/msm/registers/display/msm.xml +new file mode 100644 +index 0000000000000..429c35b73bad6 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/msm.xml +@@ -0,0 +1,32 @@ ++ ++ ++ ++ ++ ++ Register definitions for the display related hw blocks on ++ msm/snapdragon ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/display/sfpb.xml b/drivers/gpu/drm/msm/registers/display/sfpb.xml +new file mode 100644 +index 0000000000000..de1cf43c131f4 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/display/sfpb.xml +@@ -0,0 +1,17 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/freedreno_copyright.xml b/drivers/gpu/drm/msm/registers/freedreno_copyright.xml +new file mode 100644 +index 0000000000000..854efdd2e5fc0 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/freedreno_copyright.xml +@@ -0,0 +1,40 @@ ++ ++ ++ ++ ++ ++ ++Initial Author. ++ ++ ++ ++many a3xx/a4xx contributions ++ ++ ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice (including the ++next paragraph) shall be included in all copies or substantial ++portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++ ++ ++ ++ +diff --git a/drivers/gpu/drm/msm/registers/rules-fd.xsd b/drivers/gpu/drm/msm/registers/rules-fd.xsd +new file mode 100644 +index 0000000000000..2eedb099a4eb5 +--- /dev/null ++++ b/drivers/gpu/drm/msm/registers/rules-fd.xsd +@@ -0,0 +1,404 @@ ++ ++ ++ ++ ++ ++ An updated version of the old rules.xml file from the ++ RivaTV project. Specifications by Pekka Paalanen, ++ preliminary attempt by KoalaBR, ++ first working version by Jakob Bornecrantz. ++ For specifications, see the file rules-ng-format.txt ++ in Nouveau CVS module 'rules-ng'. ++ ++ Version 0.1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ register database author ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ nickType ++ ++ ++ ++ ++ ++ ++ ++ ++ databaseType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ importType ++ ++ ++ ++ ++ ++ ++ copyrightType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ domainType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ arrayType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ stripeType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ registerType used by reg32, reg64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ bitsetType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ bitfieldType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ enumType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ valueType ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ brief documentation, no markup ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ root element of documentation sub-tree ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ for bold, underline, italics ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ definition of a list, ordered or unordered ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ items of a list ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ HexOrNumber ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ DomainWidth ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.5 + diff --git a/queue-6.6/drm-nouveau-pmu-fix-gp10b-firmware-guard.patch b/queue-6.6/drm-nouveau-pmu-fix-gp10b-firmware-guard.patch new file mode 100644 index 0000000000..584390b754 --- /dev/null +++ b/queue-6.6/drm-nouveau-pmu-fix-gp10b-firmware-guard.patch @@ -0,0 +1,38 @@ +From 850cb9a0741b8eaa2a6a5e8b7b7372ae3f8a45cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 03:28:03 -0600 +Subject: drm/nouveau/pmu: Fix gp10b firmware guard + +From: Aaron Kling + +[ Upstream commit 3dbc0215e3c502a9f3221576da0fdc9847fb9721 ] + +Most kernel configs enable multiple Tegra SoC generations, causing this +typo to go unnoticed. But in the case where a kernel config is strictly +for Tegra186, this is a problem. + +Fixes: 989863d7cbe5 ("drm/nouveau/pmu: select implementation based on available firmware") +Signed-off-by: Aaron Kling +Signed-off-by: Danilo Krummrich +Link: https://patchwork.freedesktop.org/patch/msgid/20250218-nouveau-gm10b-guard-v2-1-a4de71500d48@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c +index a6f410ba60bc9..d393bc540f862 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c +@@ -75,7 +75,7 @@ gp10b_pmu_acr = { + .bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons, + }; + +-#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) ++#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) + MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin"); + MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin"); + MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin"); +-- +2.39.5 + diff --git a/queue-6.6/drm-tidss-add-simple-k2g-manual-reset.patch b/queue-6.6/drm-tidss-add-simple-k2g-manual-reset.patch new file mode 100644 index 0000000000..91783c962f --- /dev/null +++ b/queue-6.6/drm-tidss-add-simple-k2g-manual-reset.patch @@ -0,0 +1,59 @@ +From 39d8a7c79dee1027fa28f16329eb13153ce7faac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 09:38:00 +0200 +Subject: drm/tidss: Add simple K2G manual reset + +From: Tomi Valkeinen + +[ Upstream commit 576d96c5c896221b5bc8feae473739469a92e144 ] + +K2G display controller does not support soft reset, but we can do the +most important steps manually: mask the IRQs and disable the VPs. + +Reviewed-by: Aradhya Bhatia +Link: https://lore.kernel.org/r/20231109-tidss-probe-v2-7-ac91b5ea35c0@ideasonboard.com +Signed-off-by: Tomi Valkeinen +Stable-dep-of: a9a73f2661e6 ("drm/tidss: Fix race condition while handling interrupt registers") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index ee3531bbccd7d..4327e1203c565 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -2704,14 +2704,28 @@ static void dispc_init_errata(struct dispc_device *dispc) + } + } + ++/* ++ * K2G display controller does not support soft reset, so we do a basic manual ++ * reset here: make sure the IRQs are masked and VPs are disabled. ++ */ ++static void dispc_softreset_k2g(struct dispc_device *dispc) ++{ ++ dispc_set_irqenable(dispc, 0); ++ dispc_read_and_clear_irqstatus(dispc); ++ ++ for (unsigned int vp_idx = 0; vp_idx < dispc->feat->num_vps; ++vp_idx) ++ VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, 0, 0); ++} ++ + static int dispc_softreset(struct dispc_device *dispc) + { + u32 val; + int ret = 0; + +- /* K2G display controller does not support soft reset */ +- if (dispc->feat->subrev == DISPC_K2G) ++ if (dispc->feat->subrev == DISPC_K2G) { ++ dispc_softreset_k2g(dispc); + return 0; ++ } + + /* Soft reset */ + REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); +-- +2.39.5 + diff --git a/queue-6.6/drm-tidss-fix-race-condition-while-handling-interrup.patch b/queue-6.6/drm-tidss-fix-race-condition-while-handling-interrup.patch new file mode 100644 index 0000000000..f9f024c2a4 --- /dev/null +++ b/queue-6.6/drm-tidss-fix-race-condition-while-handling-interrup.patch @@ -0,0 +1,64 @@ +From dc7892e2e275525d63cf388e51b98804682e92f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 17:07:50 +0300 +Subject: drm/tidss: Fix race condition while handling interrupt registers + +From: Devarsh Thakkar + +[ Upstream commit a9a73f2661e6f625d306c9b0ef082e4593f45a21 ] + +The driver has a spinlock for protecting the irq_masks field and irq +enable registers. However, the driver misses protecting the irq status +registers which can lead to races. + +Take the spinlock when accessing irqstatus too. + +Fixes: 32a1795f57ee ("drm/tidss: New driver for TI Keystone platform Display SubSystem") +Cc: stable@vger.kernel.org +Signed-off-by: Devarsh Thakkar +[Tomi: updated the desc] +Reviewed-by: Jonathan Cormier +Tested-by: Jonathan Cormier +Reviewed-by: Aradhya Bhatia +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20241021-tidss-irq-fix-v1-6-82ddaec94e4a@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 4 ++++ + drivers/gpu/drm/tidss/tidss_irq.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 4327e1203c565..355c64bafb82b 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -2710,8 +2710,12 @@ static void dispc_init_errata(struct dispc_device *dispc) + */ + static void dispc_softreset_k2g(struct dispc_device *dispc) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dispc->tidss->wait_lock, flags); + dispc_set_irqenable(dispc, 0); + dispc_read_and_clear_irqstatus(dispc); ++ spin_unlock_irqrestore(&dispc->tidss->wait_lock, flags); + + for (unsigned int vp_idx = 0; vp_idx < dispc->feat->num_vps; ++vp_idx) + VP_REG_FLD_MOD(dispc, vp_idx, DISPC_VP_CONTROL, 0, 0, 0); +diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c +index 0c681c7600bcb..f13c7e434f8ed 100644 +--- a/drivers/gpu/drm/tidss/tidss_irq.c ++++ b/drivers/gpu/drm/tidss/tidss_irq.c +@@ -60,7 +60,9 @@ static irqreturn_t tidss_irq_handler(int irq, void *arg) + unsigned int id; + dispc_irq_t irqstatus; + ++ spin_lock(&tidss->wait_lock); + irqstatus = dispc_read_and_clear_irqstatus(tidss->dispc); ++ spin_unlock(&tidss->wait_lock); + + for (id = 0; id < tidss->num_crtcs; id++) { + struct drm_crtc *crtc = tidss->crtcs[id]; +-- +2.39.5 + diff --git a/queue-6.6/nouveau-svm-fix-missing-folio-unlock-put-after-make_.patch b/queue-6.6/nouveau-svm-fix-missing-folio-unlock-put-after-make_.patch new file mode 100644 index 0000000000..1d1a32ead8 --- /dev/null +++ b/queue-6.6/nouveau-svm-fix-missing-folio-unlock-put-after-make_.patch @@ -0,0 +1,74 @@ +From d4f87a74627a959f917dbd8faa8f274d6d8f75ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 19:15:23 +0100 +Subject: nouveau/svm: fix missing folio unlock + put after + make_device_exclusive_range() + +From: David Hildenbrand + +[ Upstream commit b3fefbb30a1691533cb905006b69b2a474660744 ] + +In case we have to retry the loop, we are missing to unlock+put the +folio. In that case, we will keep failing make_device_exclusive_range() +because we cannot grab the folio lock, and even return from the function +with the folio locked and referenced, effectively never succeeding the +make_device_exclusive_range(). + +While at it, convert the other unlock+put to use a folio as well. + +This was found by code inspection. + +Fixes: 8f187163eb89 ("nouveau/svm: implement atomic SVM access") +Signed-off-by: David Hildenbrand +Reviewed-by: Alistair Popple +Tested-by: Alistair Popple +Signed-off-by: Danilo Krummrich +Link: https://patchwork.freedesktop.org/patch/msgid/20250124181524.3584236-2-david@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nouveau_svm.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c +index ec9f307370fa8..6c71f6738ca51 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_svm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_svm.c +@@ -593,6 +593,7 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + unsigned long timeout = + jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + struct mm_struct *mm = svmm->notifier.mm; ++ struct folio *folio; + struct page *page; + unsigned long start = args->p.addr; + unsigned long notifier_seq; +@@ -619,12 +620,16 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + ret = -EINVAL; + goto out; + } ++ folio = page_folio(page); + + mutex_lock(&svmm->mutex); + if (!mmu_interval_read_retry(¬ifier->notifier, + notifier_seq)) + break; + mutex_unlock(&svmm->mutex); ++ ++ folio_unlock(folio); ++ folio_put(folio); + } + + /* Map the page on the GPU. */ +@@ -640,8 +645,8 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm, + ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL); + mutex_unlock(&svmm->mutex); + +- unlock_page(page); +- put_page(page); ++ folio_unlock(folio); ++ folio_put(folio); + + out: + mmu_interval_notifier_remove(¬ifier->notifier); +-- +2.39.5 + diff --git a/queue-6.6/nvme-ioctl-add-missing-space-in-err-message.patch b/queue-6.6/nvme-ioctl-add-missing-space-in-err-message.patch new file mode 100644 index 0000000000..3f1bbd64c3 --- /dev/null +++ b/queue-6.6/nvme-ioctl-add-missing-space-in-err-message.patch @@ -0,0 +1,41 @@ +From 69f01f80255ec2a2f5184edea982ca817d5f2a1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 10:05:14 -0700 +Subject: nvme/ioctl: add missing space in err message + +From: Caleb Sander Mateos + +[ Upstream commit 487a3ea7b1b8ba2ca7d2c2bb3c3594dc360d6261 ] + +nvme_validate_passthru_nsid() logs an err message whose format string is +split over 2 lines. There is a missing space between the two pieces, +resulting in log lines like "... does not match nsid (1)of namespace". +Add the missing space between ")" and "of". Also combine the format +string pieces onto a single line to make the err message easier to grep. + +Fixes: e7d4b5493a2d ("nvme: factor out a nvme_validate_passthru_nsid helper") +Signed-off-by: Caleb Sander Mateos +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/ioctl.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 19a7f0160618d..4ce31f9f06947 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -336,8 +336,7 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, + { + if (ns && nsid != ns->head->ns_id) { + dev_err(ctrl->device, +- "%s: nsid (%u) in cmd does not match nsid (%u)" +- "of namespace\n", ++ "%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n", + current->comm, nsid, ns->head->ns_id); + return false; + } +-- +2.39.5 + diff --git a/queue-6.6/power-supply-da9150-fg-fix-potential-overflow.patch b/queue-6.6/power-supply-da9150-fg-fix-potential-overflow.patch new file mode 100644 index 0000000000..188aa95538 --- /dev/null +++ b/queue-6.6/power-supply-da9150-fg-fix-potential-overflow.patch @@ -0,0 +1,56 @@ +From ee6ce52a6a2d18e57f39ad478a7a65bee7d68cc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2025 09:00:34 +0000 +Subject: power: supply: da9150-fg: fix potential overflow + +From: Andrey Vatoropin + +[ Upstream commit 3fb3cb4350befc4f901c54e0cb4a2a47b1302e08 ] + +Size of variable sd_gain equals four bytes - DA9150_QIF_SD_GAIN_SIZE. +Size of variable shunt_val equals two bytes - DA9150_QIF_SHUNT_VAL_SIZE. + +The expression sd_gain * shunt_val is currently being evaluated using +32-bit arithmetic. So during the multiplication an overflow may occur. + +As the value of type 'u64' is used as storage for the eventual result, put +ULL variable at the first position of each expression in order to give the +compiler complete information about the proper arithmetic to use. According +to C99 the guaranteed width for a variable of type 'unsigned long long' >= +64 bits. + +Remove the explicit cast to u64 as it is meaningless. + +Just for the sake of consistency, perform the similar trick with another +expression concerning 'iavg'. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: a419b4fd9138 ("power: Add support for DA9150 Fuel-Gauge") +Signed-off-by: Andrey Vatoropin +Link: https://lore.kernel.org/r/20250130090030.53422-1-a.vatoropin@crpt.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/da9150-fg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/da9150-fg.c b/drivers/power/supply/da9150-fg.c +index 652c1f213af1c..4f28ef1bba1a3 100644 +--- a/drivers/power/supply/da9150-fg.c ++++ b/drivers/power/supply/da9150-fg.c +@@ -247,9 +247,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg, + DA9150_QIF_SD_GAIN_SIZE); + da9150_fg_read_sync_end(fg); + +- div = (u64) (sd_gain * shunt_val * 65536ULL); ++ div = 65536ULL * sd_gain * shunt_val; + do_div(div, 1000000); +- res = (u64) (iavg * 1000000ULL); ++ res = 1000000ULL * iavg; + do_div(res, div); + + val->intval = (int) res; +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series index 48e2c45692..eb2cbc2b14 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -87,3 +87,35 @@ net-add-non-rcu-dev_getbyhwaddr-helper.patch arp-switch-to-dev_getbyhwaddr-in-arp_req_set_public.patch net-axienet-set-mac_managed_pm.patch tcp-drop-secpath-at-the-same-time-as-we-currently-dr.patch +drm-tidss-add-simple-k2g-manual-reset.patch +drm-tidss-fix-race-condition-while-handling-interrup.patch +drm-msm-gem-demote-userspace-errors-to-drm_ut_driver.patch +drm-msm-gem-prevent-integer-overflow-in-msm_ioctl_ge.patch +bpf-test_run-fix-use-after-free-issue-in-eth_skb_pkt.patch +bpf-unify-vm_write-vs-vm_maywrite-use-in-bpf-map-mma.patch +bpf-avoid-holding-freeze_mutex-during-mmap-operation.patch +strparser-add-read_sock-callback.patch +bpf-fix-wrong-copied_seq-calculation.patch +bpf-disable-non-stream-socket-for-strparser.patch +bpf-fix-deadlock-when-freeing-cgroup-storage.patch +power-supply-da9150-fg-fix-potential-overflow.patch +nouveau-svm-fix-missing-folio-unlock-put-after-make_.patch +drm-msm-avoid-rounding-up-to-one-jiffy.patch +drm-msm-dpu-rename-dpu_hw_setup_vsync_source-functio.patch +drm-msm-dpu-skip-watchdog-timer-programming-through-.patch +drm-msm-dpu-don-t-leak-bits_per_component-into-rando.patch +drm-msm-import-xml-display-registers-database.patch +drm-msm-import-a2xx-a4xx-xml-display-registers-datab.patch +drm-msm-import-a5xx-xml-display-registers-database.patch +drm-msm-import-a6xx-xml-display-registers-database.patch +drm-msm-import-gen_header.py-script-from-mesa.patch +drm-msm-generate-headers-on-the-fly.patch +drm-msm-drop-msm_read-writel.patch +drm-msm-dsi-remove-dsi_phy_read-write.patch +drm-msm-dsi-phy-protect-phy_cmn_clk_cfg0-updated-fro.patch +drm-msm-dsi-phy-protect-phy_cmn_clk_cfg1-against-clo.patch +drm-msm-dsi-phy-do-not-overwite-phy_cmn_clk_cfg1-whe.patch +nvme-ioctl-add-missing-space-in-err-message.patch +bpf-skip-non-exist-keys-in-generic_map_lookup_batch.patch +drm-nouveau-pmu-fix-gp10b-firmware-guard.patch +arm64-dts-mediatek-mt8183-disable-dsi-display-output.patch diff --git a/queue-6.6/strparser-add-read_sock-callback.patch b/queue-6.6/strparser-add-read_sock-callback.patch new file mode 100644 index 0000000000..2c289def44 --- /dev/null +++ b/queue-6.6/strparser-add-read_sock-callback.patch @@ -0,0 +1,104 @@ +From d81331403ca3f232bd3bebe5663067e57b04584c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 18:09:13 +0800 +Subject: strparser: Add read_sock callback + +From: Jiayuan Chen + +[ Upstream commit 0532a79efd68a4d9686b0385e4993af4b130ff82 ] + +Added a new read_sock handler, allowing users to customize read operations +instead of relying on the native socket's read_sock. + +Signed-off-by: Jiayuan Chen +Signed-off-by: Martin KaFai Lau +Reviewed-by: Jakub Sitnicki +Acked-by: John Fastabend +Link: https://patch.msgid.link/20250122100917.49845-2-mrpre@163.com +Stable-dep-of: 36b62df5683c ("bpf: Fix wrong copied_seq calculation") +Signed-off-by: Sasha Levin +--- + Documentation/networking/strparser.rst | 9 ++++++++- + include/net/strparser.h | 2 ++ + net/strparser/strparser.c | 11 +++++++++-- + 3 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/Documentation/networking/strparser.rst b/Documentation/networking/strparser.rst +index 6cab1f74ae05a..7f623d1db72aa 100644 +--- a/Documentation/networking/strparser.rst ++++ b/Documentation/networking/strparser.rst +@@ -112,7 +112,7 @@ Functions + Callbacks + ========= + +-There are six callbacks: ++There are seven callbacks: + + :: + +@@ -182,6 +182,13 @@ There are six callbacks: + the length of the message. skb->len - offset may be greater + then full_len since strparser does not trim the skb. + ++ :: ++ ++ int (*read_sock)(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); ++ ++ The read_sock callback is used by strparser instead of ++ sock->ops->read_sock, if provided. + :: + + int (*read_sock_done)(struct strparser *strp, int err); +diff --git a/include/net/strparser.h b/include/net/strparser.h +index 41e2ce9e9e10f..0a83010b3a64a 100644 +--- a/include/net/strparser.h ++++ b/include/net/strparser.h +@@ -43,6 +43,8 @@ struct strparser; + struct strp_callbacks { + int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); + void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); ++ int (*read_sock)(struct strparser *strp, read_descriptor_t *desc, ++ sk_read_actor_t recv_actor); + int (*read_sock_done)(struct strparser *strp, int err); + void (*abort_parser)(struct strparser *strp, int err); + void (*lock)(struct strparser *strp); +diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c +index 8299ceb3e3739..95696f42647ec 100644 +--- a/net/strparser/strparser.c ++++ b/net/strparser/strparser.c +@@ -347,7 +347,10 @@ static int strp_read_sock(struct strparser *strp) + struct socket *sock = strp->sk->sk_socket; + read_descriptor_t desc; + +- if (unlikely(!sock || !sock->ops || !sock->ops->read_sock)) ++ if (unlikely(!sock || !sock->ops)) ++ return -EBUSY; ++ ++ if (unlikely(!strp->cb.read_sock && !sock->ops->read_sock)) + return -EBUSY; + + desc.arg.data = strp; +@@ -355,7 +358,10 @@ static int strp_read_sock(struct strparser *strp) + desc.count = 1; /* give more than one skb per call */ + + /* sk should be locked here, so okay to do read_sock */ +- sock->ops->read_sock(strp->sk, &desc, strp_recv); ++ if (strp->cb.read_sock) ++ strp->cb.read_sock(strp, &desc, strp_recv); ++ else ++ sock->ops->read_sock(strp->sk, &desc, strp_recv); + + desc.error = strp->cb.read_sock_done(strp, desc.error); + +@@ -468,6 +474,7 @@ int strp_init(struct strparser *strp, struct sock *sk, + strp->cb.unlock = cb->unlock ? : strp_sock_unlock; + strp->cb.rcv_msg = cb->rcv_msg; + strp->cb.parse_msg = cb->parse_msg; ++ strp->cb.read_sock = cb->read_sock; + strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done; + strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp; + +-- +2.39.5 +