diff options
| author | Adrian Betschart <adrian.betschart@cinemaone.ch> | 2026-09-11 17:13:14 +0200 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-10-01 17:18:05 -0400 |
| commit | 106b4a2a78b2a2f14885604891957b84bba502db (patch) | |
| tree | 5d40eef2428fb1a4791ab46a4b19091a5910eac2 /include/net/protocol.h | |
| download | linux-stable-106b4a2a78b2a2f14885604891957b84bba502db.tar.gz linux-stable-106b4a2a78b2a2f14885604891957b84bba502db.zip | |
drm/amd/display: Try RGB before YCbCr 4:4:4 in stream validationgrafted
amdgpu_dm_create_validate_stream_for_sink() walks encoding_order[] and
uses the first encoding that validates. YCbCr 4:4:4 is listed before
RGB, so an HDMI sink that advertises 4:4:4 gets YCbCr 4:4:4 whenever the
"color format" property is left at AUTO, even though RGB fits the same
link.
That contradicts the documented AUTO behaviour for HDMI in enum
drm_connector_color_format (RGB, falling back to YCbCr 4:2:0 only when
the bandwidth is not available or the mode is 4:2:0-only), which the
amdgpu implementation of the property also describes. It also leaves
the "Broadcast RGB" property without effect on such sinks, since the
quantization range it selects only applies to RGB output.
Try RGB first. The mask still holds every encoding the sink supports,
so a mode that cannot carry RGB falls back exactly as before.
For reference, v7.2 picked RGB here unless YCbCr 4:4:4 was forced
through debugfs, while earlier kernels picked YCbCr 4:4:4 for any HDMI
sink that advertised it.
Fixes: 0b0ff65d3ca1 ("drm/amd/display: Refactor stream validation")
Suggested-by: Adolfo Rodrigues <adolfotregosa@gmail.com>
Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Reviewed-by: Fangzhi Zuo <jerry.zuo@amd.com>
Tested-by: Adolfo Rodrigues <adolfotregosa@gmail.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7de432bc753133764dc40d37f9388da56de251e7)
Diffstat (limited to 'include/net/protocol.h')
| -rw-r--r-- | include/net/protocol.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/include/net/protocol.h b/include/net/protocol.h new file mode 100644 index 000000000..b2499f88f --- /dev/null +++ b/include/net/protocol.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the protocol dispatcher. + * + * Version: @(#)protocol.h 1.0.2 05/07/93 + * + * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> + * + * Changes: + * Alan Cox : Added a name field and a frag handler + * field for later. + * Alan Cox : Cleaned up, and sorted types. + * Pedro Roque : inet6 protocols + */ + +#ifndef _PROTOCOL_H +#define _PROTOCOL_H + +#include <linux/in6.h> +#include <linux/skbuff.h> +#if IS_ENABLED(CONFIG_IPV6) +#include <linux/ipv6.h> +#endif +#include <linux/netdevice.h> + +/* This is one larger than the largest protocol value that can be + * found in an ipv4 or ipv6 header. Since in both cases the protocol + * value is presented in a __u8, this is defined to be 256. + */ +#define MAX_INET_PROTOS 256 + +/* This is used to register protocols. */ +struct net_protocol { + int (*handler)(struct sk_buff *skb); + + /* This returns an error if we weren't able to handle the error. */ + int (*err_handler)(struct sk_buff *skb, u32 info); + + unsigned int no_policy:1, + /* does the protocol do more stringent + * icmp tag validation than simple + * socket lookup? + */ + icmp_strict_tag_validation:1; + u32 secret; +}; + +#if IS_ENABLED(CONFIG_IPV6) +struct inet6_protocol { + int (*handler)(struct sk_buff *skb); + + /* This returns an error if we weren't able to handle the error. */ + int (*err_handler)(struct sk_buff *skb, + struct inet6_skb_parm *opt, + u8 type, u8 code, int offset, + __be32 info); + + unsigned int flags; /* INET6_PROTO_xxx */ + u32 secret; +}; + +#define INET6_PROTO_NOPOLICY 0x1 +#define INET6_PROTO_FINAL 0x2 +#endif + +struct net_offload { + struct offload_callbacks callbacks; + unsigned int flags; /* Flags used by IPv6 for now */ + u32 secret; +}; +/* This should be set for any extension header which is compatible with GSO. */ +#define INET6_PROTO_GSO_EXTHDR 0x1 + +/* This is used to register socket interfaces for IP protocols. */ +struct inet_protosw { + struct list_head list; + + /* These two fields form the lookup key. */ + unsigned short type; /* This is the 2nd argument to socket(2). */ + unsigned short protocol; /* This is the L4 protocol number. */ + + struct proto *prot; + const struct proto_ops *ops; + + unsigned char flags; /* See INET_PROTOSW_* below. */ +}; +#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ +#define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ +#define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */ + +extern struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS]; +extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS]; +extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS]; + +#if IS_ENABLED(CONFIG_IPV6) +extern struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS]; +#endif + +int inet_add_protocol(const struct net_protocol *prot, unsigned char num); +int inet_del_protocol(const struct net_protocol *prot, unsigned char num); +int inet_add_offload(const struct net_offload *prot, unsigned char num); +int inet_del_offload(const struct net_offload *prot, unsigned char num); +void inet_register_protosw(struct inet_protosw *p); +void inet_unregister_protosw(struct inet_protosw *p); + +#if IS_ENABLED(CONFIG_IPV6) +int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num); +int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num); +int inet6_register_protosw(struct inet_protosw *p); +void inet6_unregister_protosw(struct inet_protosw *p); +#endif +int inet6_add_offload(const struct net_offload *prot, unsigned char num); +int inet6_del_offload(const struct net_offload *prot, unsigned char num); + +#endif /* _PROTOCOL_H */ |
