diff --git a/lib/libcrypto/cms/cms_lib.c b/lib/libcrypto/cms/cms_lib.c index fc899437a..8a8fdbc8d 100644 --- a/lib/libcrypto/cms/cms_lib.c +++ b/lib/libcrypto/cms/cms_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cms_lib.c,v 1.21 2023/08/22 08:59:44 tb Exp $ */ +/* $OpenBSD: cms_lib.c,v 1.24 2023/08/24 04:56:36 tb Exp $ */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -121,55 +121,55 @@ cms_Data_create(void) return cms; } -BIO * +static BIO * cms_content_bio(CMS_ContentInfo *cms) { - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + ASN1_OCTET_STRING **pos; - if (!pos) + if ((pos = CMS_get0_content(cms)) == NULL) return NULL; - /* If content detached data goes nowhere: create NULL BIO */ - if (!*pos) + + /* If content is detached, data goes nowhere: create null BIO. */ + if (*pos == NULL) return BIO_new(BIO_s_null()); - /* - * If content not detached and created return memory BIO - */ - if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) + + /* If content is not detached and was created, return memory BIO. */ + if ((*pos)->flags == ASN1_STRING_FLAG_CONT) return BIO_new(BIO_s_mem()); - /* Else content was read in: return read only BIO for it */ + /* Else content was read in: return read-only BIO for it. */ return BIO_new_mem_buf((*pos)->data, (*pos)->length); } BIO * -CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) +CMS_dataInit(CMS_ContentInfo *cms, BIO *in_content_bio) { - BIO *cmsbio = NULL, *cont = NULL; + BIO *cms_bio = NULL, *content_bio = NULL; - if ((cont = icont) == NULL) - cont = cms_content_bio(cms); - if (cont == NULL) { + if ((content_bio = in_content_bio) == NULL) + content_bio = cms_content_bio(cms); + if (content_bio == NULL) { CMSerror(CMS_R_NO_CONTENT); goto err; } switch (OBJ_obj2nid(cms->contentType)) { case NID_pkcs7_data: - return cont; + return content_bio; case NID_pkcs7_signed: - if ((cmsbio = cms_SignedData_init_bio(cms)) == NULL) + if ((cms_bio = cms_SignedData_init_bio(cms)) == NULL) goto err; break; case NID_pkcs7_digest: - if ((cmsbio = cms_DigestedData_init_bio(cms)) == NULL) + if ((cms_bio = cms_DigestedData_init_bio(cms)) == NULL) goto err; break; case NID_pkcs7_encrypted: - if ((cmsbio = cms_EncryptedData_init_bio(cms)) == NULL) + if ((cms_bio = cms_EncryptedData_init_bio(cms)) == NULL) goto err; break; case NID_pkcs7_enveloped: - if ((cmsbio = cms_EnvelopedData_init_bio(cms)) == NULL) + if ((cms_bio = cms_EnvelopedData_init_bio(cms)) == NULL) goto err; break; default: @@ -177,11 +177,11 @@ CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) goto err; } - return BIO_push(cmsbio, cont); + return BIO_push(cms_bio, content_bio); err: - if (cont != icont) - BIO_free(cont); + if (content_bio != in_content_bio) + BIO_free(content_bio); return NULL; } diff --git a/lib/libcrypto/cms/cms_local.h b/lib/libcrypto/cms/cms_local.h index 7d8032fb4..2e3a3637e 100644 --- a/lib/libcrypto/cms/cms_local.h +++ b/lib/libcrypto/cms/cms_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cms_local.h,v 1.4 2023/07/07 16:04:57 tb Exp $ */ +/* $OpenBSD: cms_local.h,v 1.5 2023/08/24 04:56:36 tb Exp $ */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -410,8 +410,6 @@ void CMS_IssuerAndSerialNumber_free(CMS_IssuerAndSerialNumber *a); #define CMS_OIK_KEYIDENTIFIER 1 #define CMS_OIK_PUBKEY 2 -BIO *cms_content_bio(CMS_ContentInfo *cms); - CMS_ContentInfo *cms_Data_create(void); CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); diff --git a/lib/libcrypto/evp/e_chacha.c b/lib/libcrypto/evp/e_chacha.c index add048847..5cd03c7c8 100644 --- a/lib/libcrypto/evp/e_chacha.c +++ b/lib/libcrypto/evp/e_chacha.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_chacha.c,v 1.12 2023/07/07 19:37:53 beck Exp $ */ +/* $OpenBSD: e_chacha.c,v 1.13 2023/08/24 04:20:57 tb Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -53,13 +53,11 @@ static const EVP_CIPHER chacha20_cipher = { .nid = NID_chacha20, .block_size = 1, .key_len = 32, - /* - * The 128 bit EVP IV is split for ChaCha into four 32 bit pieces: - * counter[0] counter[1] iv[0] iv[1] - * OpenSSL exposes these as: - * openssl_iv = counter[0] iv[0] iv[1] iv[2] - * Due to the cipher internal state's symmetry, these are functionally - * equivalent. + /* + * The 16-byte EVP IV is split into 4 little-endian 4-byte words + * evpiv[15:12] evpiv[11:8] evpiv[7:4] evpiv[3:0] + * iv[1] iv[0] counter[1] counter[0] + * and passed as iv[] and counter[] to ChaCha_set_iv(). */ .iv_len = 16, .flags = EVP_CIPH_STREAM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | diff --git a/lib/libcrypto/evp/e_chacha20poly1305.c b/lib/libcrypto/evp/e_chacha20poly1305.c index a17657899..33d09315e 100644 --- a/lib/libcrypto/evp/e_chacha20poly1305.c +++ b/lib/libcrypto/evp/e_chacha20poly1305.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_chacha20poly1305.c,v 1.30 2023/07/07 19:37:53 beck Exp $ */ +/* $OpenBSD: e_chacha20poly1305.c,v 1.31 2023/08/24 04:33:08 tb Exp $ */ /* * Copyright (c) 2022 Joel Sing @@ -106,7 +106,7 @@ poly1305_pad16(poly1305_state *poly1305, size_t data_len) static const unsigned char zero_pad16[16]; size_t pad_len; - /* pad16() is defined in RFC 7539 2.8.1. */ + /* pad16() is defined in RFC 8439 2.8.1. */ if ((pad_len = data_len % 16) == 0) return; @@ -330,7 +330,7 @@ aead_xchacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, return 1; } -/* RFC 7539 */ +/* RFC 8439 */ static const EVP_AEAD aead_chacha20_poly1305 = { .key_len = 32, .nonce_len = CHACHA20_NONCE_LEN, diff --git a/lib/libcrypto/man/EVP_AEAD_CTX_init.3 b/lib/libcrypto/man/EVP_AEAD_CTX_init.3 index 269dcbd9f..ad37842cc 100644 --- a/lib/libcrypto/man/EVP_AEAD_CTX_init.3 +++ b/lib/libcrypto/man/EVP_AEAD_CTX_init.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.11 2023/05/09 07:19:24 tb Exp $ +.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.13 2023/08/24 04:33:08 tb Exp $ .\" .\" Copyright (c) 2014, Google Inc. .\" Parts of the text were written by Adam Langley and David Benjamin. @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: May 9 2023 $ +.Dd $Mdocdate: August 24 2023 $ .Dt EVP_AEAD_CTX_INIT 3 .Os .Sh NAME @@ -245,23 +245,44 @@ All cipher algorithms have a fixed key length unless otherwise stated. The following ciphers are available: .Bl -tag -width Ds -offset indent .It Fn EVP_aead_aes_128_gcm -AES-128 in Galois Counter Mode. +AES-128 in Galois Counter Mode, using a +.Fa key_len +of 16 bytes and a +.Fa nonce_len +of 12 bytes. .It Fn EVP_aead_aes_256_gcm -AES-256 in Galois Counter Mode. +AES-256 in Galois Counter Mode, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 12 bytes. .It Fn EVP_aead_chacha20_poly1305 -ChaCha20 with a Poly1305 authenticator. +ChaCha20 with a Poly1305 authenticator, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 12 bytes. .It Fn EVP_aead_xchacha20_poly1305 -XChaCha20 with a Poly1305 authenticator. +XChaCha20 with a Poly1305 authenticator, using a +.Fa key_len +of 32 bytes and a +.Fa nonce_len +of 24 bytes. .El .Pp -Where possible the +Unless compatibility with other implementations +like OpenSSL or BoringSSL is required, using the .Sy EVP_AEAD -interface to AEAD ciphers should be used in preference to the older -.Sy EVP -variants or to the low level interfaces. -This is because the code then becomes transparent to the AEAD cipher -used and much more flexible. -It is also safer to use as it prevents common mistakes with the native APIs. +interface to AEAD ciphers is recommended +in preference to the functions documented in the +.Xr EVP_EncryptInit 3 , +.Xr EVP_aes_256_gcm 3 , +and +.Xr EVP_chacha20_poly1305 3 +manual pages. +The code then becomes transparent to the AEAD cipher used +and much more flexible. +It is also safer to use as it prevents common mistakes with the EVP APIs. .Sh RETURN VALUES .Fn EVP_AEAD_CTX_new returns the new @@ -319,17 +340,12 @@ EVP_AEAD_CTX_free(ctx); .Rs .%A A. Langley .%A W. Chang -.%D November 2013 -.%R draft-agl-tls-chacha20poly1305-04 -.%T ChaCha20 and Poly1305 based Cipher Suites for TLS -.Re -.Pp -.Rs -.%A Y. Nir -.%A A. Langley -.%D May 2015 -.%R RFC 7539 -.%T ChaCha20 and Poly1305 for IETF Protocols +.%A N. Mavrogiannopoulos +.%A J. Strombergson +.%A S. Josefsson +.%D June 2016 +.%R RFC 7905 +.%T ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) .Re .Pp .Rs @@ -341,6 +357,7 @@ EVP_AEAD_CTX_free(ctx); .Sh HISTORY AEAD is based on the implementation by .An Adam Langley +.\" OpenSSL commit 9a8646510b Sep 9 12:13:24 2013 -0400 for Chromium/BoringSSL and first appeared in .Ox 5.6 . .Pp @@ -349,3 +366,28 @@ and .Fn EVP_AEAD_CTX_free first appeared in .Ox 7.1 . +.Sh CAVEATS +The original publications and code by +.An Adam Langley +used a modified AEAD construction that is incompatible with the common +style used by AEAD in TLS and incompatible with RFC 7905: +.Pp +.Rs +.%A A. Langley +.%A W. Chang +.%D November 2013 +.%R draft-agl-tls-chacha20poly1305-04 +.%T ChaCha20 and Poly1305 based Cipher Suites for TLS +.Re +.Pp +.Rs +.%A Y. Nir +.%A A. Langley +.%D June 2018 +.%R RFC 8439 +.%T ChaCha20 and Poly1305 for IETF Protocols +.Re +.Pp +In particular, the original version used a +.Fa nonce_len +of 8 bytes. diff --git a/lib/libcrypto/man/EVP_chacha20.3 b/lib/libcrypto/man/EVP_chacha20.3 index 8d9ea068f..14a26b304 100644 --- a/lib/libcrypto/man/EVP_chacha20.3 +++ b/lib/libcrypto/man/EVP_chacha20.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: EVP_chacha20.3,v 1.3 2023/08/21 03:26:42 jsg Exp $ +.\" $OpenBSD: EVP_chacha20.3,v 1.6 2023/08/24 04:33:08 tb Exp $ .\" full merge up to: OpenSSL 35fd9953 May 28 14:49:38 2019 +0200 .\" .\" This file is a derived work. @@ -65,7 +65,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 21 2023 $ +.Dd $Mdocdate: August 24 2023 $ .Dt EVP_CHACHA20 3 .Os .Sh NAME @@ -93,11 +93,11 @@ argument of 16 bytes = 128 bits, internally using .Xr ChaCha_set_key 3 and .Xr ChaCha_set_iv 3 . -Due to the symmetry of the internal cipher state, interpreting the +The lower 8 bytes = 64 bits of .Fa iv -argument as a 4 byte counter followed by a 12 byte nonce -or interpreting it as an 8 byte counter followed by an 8 byte nonce -is functionally equivalent. +are used as counter and the remaining 8 bytes are used as +the initialization vector of +.Xr ChaCha_set_iv 3 . .Xr EVP_EncryptUpdate 3 , .Xr EVP_EncryptFinal_ex 3 , .Xr EVP_DecryptUpdate 3 , @@ -114,6 +114,16 @@ objects created from .Pp .Fn EVP_chacha20_poly1305 provides authenticated encryption with ChaCha20-Poly1305. +Unless compatibility with other implementations +like OpenSSL or BoringSSL is required, using +.Xr EVP_AEAD_CTX_init 3 +with +.Xr EVP_aead_chacha20_poly1305 3 +is recommended instead because the code then becomes transparent +to the AEAD cipher used, more flexible, and less error prone. +.Pp +With +.Fn EVP_chacha20_poly1305 , .Xr EVP_EncryptInit_ex 3 , .Xr EVP_DecryptInit_ex 3 , and @@ -237,6 +247,32 @@ returns 1 for success or 0 for failure. .Rs .%A A. Langley .%A W. Chang +.%A N. Mavrogiannopoulos +.%A J. Strombergson +.%A S. Josefsson +.%D June 2016 +.%R RFC 7905 +.%T ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) +.Re +.Sh HISTORY +.Fn EVP_chacha20 +first appeared in +.Ox 5.6 . +.Pp +.Fn EVP_chacha20_poly1305 +first appeared in OpenSSL 1.1.0 +.\" OpenSSL commit bd989745 Dec 9 21:30:56 2015 +0100 Andy Polyakov +and has been available since +.Ox 7.2 . +.Sh CAVEATS +The original publications and code by +.An Adam Langley +used a modified AEAD construction that is incompatible with the common +style used by AEAD in TLS and incompatible with RFC 7905: +.Pp +.Rs +.%A A. Langley +.%A W. Chang .%D November 2013 .%R draft-agl-tls-chacha20poly1305-04 .%T ChaCha20 and Poly1305 based Cipher Suites for TLS @@ -245,15 +281,9 @@ returns 1 for success or 0 for failure. .Rs .%A Y. Nir .%A A. Langley -.%D May 2015 -.%R RFC 7539 +.%D May 2018 +.%R RFC 8439 .%T ChaCha20 and Poly1305 for IETF Protocols .Re -.Sh HISTORY -.Fn EVP_chacha20 -first appeared in -.Ox 5.6 . .Pp -.Fn EVP_chacha20_poly1305 -first appeared in OpenSSL 1.1.0 and has been available since -.Ox 7.2 . +In particular, the original version used a nonce of 8 instead of 12 bytes. diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c index da17b0875..4e7182ecb 100644 --- a/sys/arch/amd64/amd64/lapic.c +++ b/sys/arch/amd64/amd64/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.68 2023/04/26 10:52:55 mlarkin Exp $ */ +/* $OpenBSD: lapic.c,v 1.69 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */ /*- @@ -499,8 +499,6 @@ lapic_initclocks(void) stathz = hz; profhz = stathz * 10; clockintr_init(CL_RNDSTAT); - - lapic_startclock(); } @@ -599,6 +597,7 @@ skip_calibration: lapic_per_second * (1ULL << 32) / 1000000000; lapic_timer_nsec_max = UINT64_MAX / lapic_timer_nsec_cycle_ratio; initclock_func = lapic_initclocks; + startclock_func = lapic_startclock; } /* diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 453de13fb..8c5f398b8 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.286 2023/07/27 00:28:25 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.287 2023/08/23 01:55:45 cheloha Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -227,6 +227,7 @@ paddr_t avail_end; void (*delay_func)(int) = i8254_delay; void (*initclock_func)(void) = i8254_initclocks; +void (*startclock_func)(void) = i8254_start_both_clocks; /* * Format of boot information passed to us by 32-bit /boot @@ -1880,6 +1881,12 @@ cpu_initclocks(void) (*initclock_func)(); } +void +cpu_startclock(void) +{ + (*startclock_func)(); +} + void need_resched(struct cpu_info *ci) { diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index cf3228862..9069c3df8 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.158 2023/07/27 00:28:24 guenther Exp $ */ +/* $OpenBSD: cpu.h,v 1.159 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -408,6 +408,8 @@ int amd64_pa_used(paddr_t); extern void (*cpu_idle_cycle_fcn)(void); #define cpu_idle_cycle() (*cpu_idle_cycle_fcn)() #define cpu_idle_leave() do { /* nothing */ } while (0) +extern void (*initclock_func)(void); +extern void (*startclock_func)(void); struct region_descriptor; void lgdt(struct region_descriptor *); @@ -418,7 +420,6 @@ void switch_exit(struct proc *, void (*)(struct proc *)); void proc_trampoline(void); /* clock.c */ -extern void (*initclock_func)(void); void startclocks(void); void rtcinit(void); void rtcstart(void); @@ -426,6 +427,7 @@ void rtcstop(void); void i8254_delay(int); void i8254_initclocks(void); void i8254_startclock(void); +void i8254_start_both_clocks(void); void i8254_inittimecounter(void); void i8254_inittimecounter_simple(void); diff --git a/sys/arch/amd64/isa/clock.c b/sys/arch/amd64/isa/clock.c index 019259ffd..3dd79b176 100644 --- a/sys/arch/amd64/isa/clock.c +++ b/sys/arch/amd64/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.40 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.41 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */ /*- @@ -284,7 +284,11 @@ i8254_initclocks(void) stathz = 128; profhz = 1024; /* XXX does not divide into 1 billion */ clockintr_init(0); +} +void +i8254_start_both_clocks(void) +{ clockintr_cpu_init(NULL); /* diff --git a/sys/arch/arm/cortex/agtimer.c b/sys/arch/arm/cortex/agtimer.c index 13b0af6f8..88e201abe 100644 --- a/sys/arch/arm/cortex/agtimer.c +++ b/sys/arch/arm/cortex/agtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agtimer.c,v 1.18 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: agtimer.c,v 1.19 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * Copyright (c) 2013 Patrick Wildt @@ -227,7 +227,6 @@ void agtimer_cpu_initclocks(void) { struct agtimer_softc *sc = agtimer_cd.cd_devs[0]; - uint32_t reg; stathz = hz; profhz = stathz * 10; @@ -237,21 +236,11 @@ agtimer_cpu_initclocks(void) agtimer_set_clockrate(agtimer_frequency); } - clockintr_cpu_init(&agtimer_intrclock); - /* Setup secure and non-secure timer IRQs. */ arm_intr_establish_fdt_idx(sc->sc_node, 0, IPL_CLOCK, agtimer_intr, NULL, "tick"); arm_intr_establish_fdt_idx(sc->sc_node, 1, IPL_CLOCK, agtimer_intr, NULL, "tick"); - - reg = agtimer_get_ctrl(); - reg &= ~GTIMER_CNTP_CTL_IMASK; - reg |= GTIMER_CNTP_CTL_ENABLE; - agtimer_set_tval(INT32_MAX); - agtimer_set_ctrl(reg); - - clockintr_trigger(); } void diff --git a/sys/arch/arm/cortex/amptimer.c b/sys/arch/arm/cortex/amptimer.c index 6fcf49579..299f9fe8c 100644 --- a/sys/arch/arm/cortex/amptimer.c +++ b/sys/arch/arm/cortex/amptimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: amptimer.c,v 1.17 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: amptimer.c,v 1.18 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * @@ -301,10 +301,6 @@ amptimer_cpu_initclocks(void) /* Enable private timer counter and interrupt. */ bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL, (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)); - - /* Start the clock interrupt cycle. */ - clockintr_cpu_init(&timer_intrclock); - clockintr_trigger(); } void diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 9bc162dcc..f42b7b3ab 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.63 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.64 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -329,8 +329,6 @@ intr_restore(u_long cpsr) __asm volatile ("msr cpsr_c, %0" :: "r"(cpsr)); } -void cpu_startclock(void); - #endif /* _KERNEL */ #ifdef MULTIPROCESSOR diff --git a/sys/arch/arm64/dev/agtimer.c b/sys/arch/arm64/dev/agtimer.c index 32f068814..14fb14f00 100644 --- a/sys/arch/arm64/dev/agtimer.c +++ b/sys/arch/arm64/dev/agtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agtimer.c,v 1.25 2023/08/11 01:28:19 cheloha Exp $ */ +/* $OpenBSD: agtimer.c,v 1.26 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2011 Dale Rahn * Copyright (c) 2013 Patrick Wildt @@ -290,8 +290,6 @@ void agtimer_cpu_initclocks(void) { struct agtimer_softc *sc = agtimer_cd.cd_devs[0]; - uint32_t reg; - uint64_t kctl; stathz = hz; profhz = stathz * 10; @@ -304,20 +302,6 @@ agtimer_cpu_initclocks(void) /* configure virtual timer interrupt */ sc->sc_ih = arm_intr_establish_fdt_idx(sc->sc_node, 2, IPL_CLOCK|IPL_MPSAFE, agtimer_intr, NULL, "tick"); - - clockintr_cpu_init(&agtimer_intrclock); - - reg = agtimer_get_ctrl(); - reg &= ~GTIMER_CNTV_CTL_IMASK; - reg |= GTIMER_CNTV_CTL_ENABLE; - agtimer_set_tval(INT32_MAX); - agtimer_set_ctrl(reg); - - clockintr_trigger(); - - /* enable userland access to virtual counter */ - kctl = READ_SPECIALREG(CNTKCTL_EL1); - WRITE_SPECIALREG(CNTKCTL_EL1, kctl | CNTKCTL_EL0VCTEN); } void @@ -343,7 +327,8 @@ agtimer_startclock(void) uint64_t kctl; uint32_t reg; - arm_intr_route(sc->sc_ih, 1, curcpu()); + if (!CPU_IS_PRIMARY(curcpu())) + arm_intr_route(sc->sc_ih, 1, curcpu()); clockintr_cpu_init(&agtimer_intrclock); diff --git a/sys/arch/arm64/include/cpu.h b/sys/arch/arm64/include/cpu.h index ab9fdcb37..ec514d8e4 100644 --- a/sys/arch/arm64/include/cpu.h +++ b/sys/arch/arm64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.38 2023/07/25 18:16:20 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.39 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2016 Dale Rahn * @@ -344,7 +344,6 @@ intr_restore(u_long daif) } void cpu_halt(void); -void cpu_startclock(void); int cpu_suspend_primary(void); void cpu_resume_secondary(struct cpu_info *); diff --git a/sys/arch/armv7/omap/dmtimer.c b/sys/arch/armv7/omap/dmtimer.c index b1dfcb48c..e0d4b11ce 100644 --- a/sys/arch/armv7/omap/dmtimer.c +++ b/sys/arch/armv7/omap/dmtimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dmtimer.c,v 1.19 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: dmtimer.c,v 1.20 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2013 Raphael Graf @@ -102,6 +102,7 @@ int dmtimer_intr(void *frame); void dmtimer_reset_tisr(void); void dmtimer_wait(int reg); void dmtimer_cpu_initclocks(void); +void dmtimer_cpu_startclock(void); void dmtimer_delay(u_int); void dmtimer_setstatclockrate(int newhz); @@ -195,7 +196,7 @@ dmtimer_attach(struct device *parent, struct device *self, void *args) dmtimer_timecounter.tc_priv = sc; tc_init(&dmtimer_timecounter); arm_clock_register(dmtimer_cpu_initclocks, dmtimer_delay, - dmtimer_setstatclockrate, NULL); + dmtimer_setstatclockrate, dmtimer_cpu_startclock); } else panic("attaching too many dmtimers at 0x%lx", @@ -247,7 +248,11 @@ dmtimer_cpu_initclocks(void) bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TLDR, 0); bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TIER, DM_TIER_OVF_EN); bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TWER, DM_TWER_OVF_EN); +} +void +dmtimer_cpu_startclock(void) +{ /* start the clock interrupt cycle */ clockintr_cpu_init(&dmtimer_intrclock); clockintr_trigger(); diff --git a/sys/arch/armv7/omap/gptimer.c b/sys/arch/armv7/omap/gptimer.c index ee9fa842a..10921d409 100644 --- a/sys/arch/armv7/omap/gptimer.c +++ b/sys/arch/armv7/omap/gptimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gptimer.c,v 1.20 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: gptimer.c,v 1.21 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * @@ -99,6 +99,7 @@ void gptimer_attach(struct device *parent, struct device *self, void *args); int gptimer_intr(void *frame); void gptimer_wait(int reg); void gptimer_cpu_initclocks(void); +void gptimer_cpu_startclock(void); void gptimer_delay(u_int); void gptimer_reset_tisr(void); void gptimer_setstatclockrate(int newhz); @@ -176,7 +177,7 @@ gptimer_attach(struct device *parent, struct device *self, void *args) aa->aa_dev->mem[0].addr); arm_clock_register(gptimer_cpu_initclocks, gptimer_delay, - gptimer_setstatclockrate, NULL); + gptimer_setstatclockrate, gptimer_cpu_startclock); } int @@ -216,7 +217,11 @@ gptimer_cpu_initclocks(void) gptimer_wait(GP_TWPS_ALL); bus_space_write_4(gptimer_iot, gptimer_ioh0, GP_TWER, GP_TWER_OVF_EN); gptimer_wait(GP_TWPS_ALL); +} +void +gptimer_cpu_startclock(void) +{ /* start the clock interrupt cycle */ clockintr_cpu_init(&gptimer_intrclock); clockintr_trigger(); diff --git a/sys/arch/armv7/sunxi/sxitimer.c b/sys/arch/armv7/sunxi/sxitimer.c index a0db9b62d..5418e0540 100644 --- a/sys/arch/armv7/sunxi/sxitimer.c +++ b/sys/arch/armv7/sunxi/sxitimer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sxitimer.c,v 1.21 2023/07/25 18:16:19 cheloha Exp $ */ +/* $OpenBSD: sxitimer.c,v 1.22 2023/08/23 01:55:46 cheloha Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2013 Raphael Graf @@ -77,6 +77,7 @@ void sxitimer_attach(struct device *, struct device *, void *); int sxitimer_tickintr(void *); int sxitimer_statintr(void *); void sxitimer_cpu_initclocks(void); +void sxitimer_cpu_startclock(void); void sxitimer_setstatclockrate(int); uint64_t sxitimer_readcnt64(void); uint32_t sxitimer_readcnt32(void); @@ -191,7 +192,7 @@ sxitimer_attach(struct device *parent, struct device *self, void *aux) tc_init(&sxitimer_timecounter); arm_clock_register(sxitimer_cpu_initclocks, sxitimer_delay, - sxitimer_setstatclockrate, NULL); + sxitimer_setstatclockrate, sxitimer_cpu_startclock); printf(": %d kHz", sxitimer_freq[CNTRTIMER] / 1000); @@ -229,7 +230,11 @@ sxitimer_cpu_initclocks(void) bus_space_write_4(sxitimer_iot, sxitimer_ioh, TIMER_CTRL(CNTRTIMER), ctrl | TIMER_ENABLE | TIMER_RELOAD | TIMER_CONTINOUS); +} +void +sxitimer_cpu_startclock(void) +{ /* start clock interrupt cycle */ clockintr_cpu_init(&sxitimer_intrclock); clockintr_trigger(); diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c index 7959c0edb..1eaf55b45 100644 --- a/sys/arch/i386/i386/lapic.c +++ b/sys/arch/i386/i386/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.55 2023/02/09 01:41:15 cheloha Exp $ */ +/* $OpenBSD: lapic.c,v 1.56 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */ /*- @@ -327,8 +327,6 @@ lapic_initclocks(void) stathz = hz; profhz = stathz * 10; clockintr_init(CL_RNDSTAT); - - lapic_startclock(); } extern int gettick(void); /* XXX put in header file */ @@ -422,6 +420,7 @@ lapic_calibrate_timer(struct cpu_info *ci) lapic_per_second * (1ULL << 32) / 1000000000; lapic_timer_nsec_max = UINT64_MAX / lapic_timer_nsec_cycle_ratio; initclock_func = lapic_initclocks; + startclock_func = lapic_startclock; } /* diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 9ade46b53..46a08b79f 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.668 2023/08/16 09:51:39 jsg Exp $ */ +/* $OpenBSD: machdep.c,v 1.669 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -233,6 +233,7 @@ void (*cpusensors_setup)(struct cpu_info *); void (*delay_func)(int) = i8254_delay; void (*initclock_func)(void) = i8254_initclocks; +void (*startclock_func)(void) = i8254_start_both_clocks; /* * Extent maps to manage I/O and ISA memory hole space. Allocate @@ -3438,6 +3439,12 @@ cpu_initclocks(void) (*initclock_func)(); /* lapic or i8254 */ } +void +cpu_startclock(void) +{ + (*startclock_func)(); +} + void need_resched(struct cpu_info *ci) { diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index 6f068fa5a..ae604fc5d 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.182 2023/07/25 18:16:20 cheloha Exp $ */ +/* $OpenBSD: cpu.h,v 1.183 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -399,6 +399,9 @@ extern int i386_has_sse2; extern void (*update_cpuspeed)(void); +extern void (*initclock_func)(void); +extern void (*startclock_func)(void); + /* machdep.c */ void dumpconf(void); void cpu_reset(void); @@ -416,7 +419,6 @@ void switch_exit(struct proc *); void proc_trampoline(void); /* clock.c */ -extern void (*initclock_func)(void); void startclocks(void); void rtcinit(void); void rtcstart(void); @@ -424,6 +426,7 @@ void rtcstop(void); void i8254_delay(int); void i8254_initclocks(void); void i8254_startclock(void); +void i8254_start_both_clocks(void); void i8254_inittimecounter(void); void i8254_inittimecounter_simple(void); diff --git a/sys/arch/i386/isa/clock.c b/sys/arch/i386/isa/clock.c index f9b7c96a8..d7b6f3c40 100644 --- a/sys/arch/i386/isa/clock.c +++ b/sys/arch/i386/isa/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.66 2023/08/22 17:13:22 cheloha Exp $ */ +/* $OpenBSD: clock.c,v 1.67 2023/08/23 01:55:46 cheloha Exp $ */ /* $NetBSD: clock.c,v 1.39 1996/05/12 23:11:54 mycroft Exp $ */ /*- @@ -427,7 +427,11 @@ i8254_initclocks(void) stathz = 128; profhz = 1024; /* XXX does not divide into 1 billion */ clockintr_init(0); +} +void +i8254_start_both_clocks(void) +{ clockintr_cpu_init(NULL); /* diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_cs.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_cs.c index b2b64a6f7..050892687 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_cs.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_cs.c @@ -185,7 +185,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, uint64_t *chunk_array_user; uint64_t *chunk_array; uint32_t uf_offset = 0; - unsigned int size; + size_t size; int ret; int i; @@ -1609,15 +1609,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, continue; r = dma_fence_wait_timeout(fence, true, timeout); + if (r > 0 && fence->error) + r = fence->error; + dma_fence_put(fence); if (r < 0) return r; if (r == 0) break; - - if (fence->error) - return fence->error; } memset(wait, 0, sizeof(*wait)); diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c index 73fa47c34..8bad65c85 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c @@ -4354,6 +4354,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); cancel_delayed_work_sync(&adev->delayed_init_work); + flush_delayed_work(&adev->gfx.gfx_off_delay_work); amdgpu_ras_suspend(adev); diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c index 8770aa59d..07aa8c322 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c @@ -518,6 +518,41 @@ int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev) return 0; } +/** + * amdgpu_fence_need_ring_interrupt_restore - helper function to check whether + * fence driver interrupts need to be restored. + * + * @ring: ring that to be checked + * + * Interrupts for rings that belong to GFX IP don't need to be restored + * when the target power state is s0ix. + * + * Return true if need to restore interrupts, false otherwise. + */ +static bool amdgpu_fence_need_ring_interrupt_restore(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + bool is_gfx_power_domain = false; + + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_SDMA: + /* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */ + if (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) + is_gfx_power_domain = true; + break; + case AMDGPU_RING_TYPE_GFX: + case AMDGPU_RING_TYPE_COMPUTE: + case AMDGPU_RING_TYPE_KIQ: + case AMDGPU_RING_TYPE_MES: + is_gfx_power_domain = true; + break; + default: + break; + } + + return !(adev->in_s0ix && is_gfx_power_domain); +} + /** * amdgpu_fence_driver_hw_fini - tear down the fence driver * for all possible rings. @@ -546,7 +581,8 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) amdgpu_fence_driver_force_completion(ring); if (!drm_dev_is_unplugged(adev_to_drm(adev)) && - ring->fence_drv.irq_src) + ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); @@ -624,7 +660,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) continue; /* enable the interrupt */ - if (ring->fence_drv.irq_src) + if (ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_get(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); } diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c index df5255c4a..18578db21 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c @@ -587,15 +587,8 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) { - /* If going to s2idle, no need to wait */ - if (adev->in_s0ix) { - if (!amdgpu_dpm_set_powergating_by_smu(adev, - AMD_IP_BLOCK_TYPE_GFX, true)) - adev->gfx.gfx_off_state = true; - } else { - schedule_delayed_work(&adev->gfx.gfx_off_delay_work, + schedule_delayed_work(&adev->gfx.gfx_off_delay_work, delay); - } } } else { if (adev->gfx.gfx_off_req_count == 0) { diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c index 9190712d2..800dbdd38 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c @@ -160,7 +160,6 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) continue; for (k = 0; k < src->num_types; ++k) { - atomic_set(&src->enabled_types[k], 0); r = src->funcs->set(adev, src, k, AMDGPU_IRQ_STATE_DISABLE); if (r) diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c index 612c2cdde..61ef080ff 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_psp.c @@ -514,6 +514,8 @@ static int psp_sw_fini(void *handle) kfree(cmd); cmd = NULL; + psp_free_shared_bufs(psp); + if (psp->km_ring.ring_mem) amdgpu_bo_free_kernel(&adev->firmware.rbuf, &psp->km_ring.ring_mem_mc_addr, @@ -2686,8 +2688,6 @@ static int psp_hw_fini(void *handle) psp_ring_destroy(psp, PSP_RING_TYPE__KM); - psp_free_shared_bufs(psp); - return 0; } diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_ring.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_ring.c index d3558c34d..296b2d597 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_ring.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_ring.c @@ -361,6 +361,8 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) amdgpu_bo_free_kernel(&ring->ring_obj, &ring->gpu_addr, (void **)&ring->ring); + } else { + kfree(ring->fence_drv.fences); } dma_fence_put(ring->vmid_wait); diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm.c index 54e47f300..f8f245781 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_vm.c @@ -1414,6 +1414,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, amdgpu_vm_bo_base_init(&bo_va->base, vm, bo); bo_va->ref_count = 1; + bo_va->last_pt_update = dma_fence_get_stub(); INIT_LIST_HEAD(&bo_va->valids); INIT_LIST_HEAD(&bo_va->invalids); @@ -2142,7 +2143,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) vm->update_funcs = &amdgpu_vm_cpu_funcs; else vm->update_funcs = &amdgpu_vm_sdma_funcs; - vm->last_update = NULL; + + vm->last_update = dma_fence_get_stub(); vm->last_unlocked = dma_fence_get_stub(); vm->last_tlb_flush = dma_fence_get_stub(); @@ -2271,7 +2273,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) goto unreserve_bo; dma_fence_put(vm->last_update); - vm->last_update = NULL; + vm->last_update = dma_fence_get_stub(); vm->is_compute_context = true; /* Free the shadow bo for compute VM */ diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 25febd19d..218634816 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7401,27 +7401,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state, } #ifdef CONFIG_DRM_AMD_DC_HDCP -static bool is_content_protection_different(struct drm_connector_state *state, - const struct drm_connector_state *old_state, - const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w) +static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state, + struct drm_crtc_state *old_crtc_state, + struct drm_connector_state *new_conn_state, + struct drm_connector_state *old_conn_state, + const struct drm_connector *connector, + struct hdcp_workqueue *hdcp_w) { struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); - /* Handle: Type0/1 change */ - if (old_state->hdcp_content_type != state->hdcp_content_type && - state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { - state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; + pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", + connector->index, connector->status, connector->dpms); + pr_debug("[HDCP_DM] state protection old: %x new: %x\n", + old_conn_state->content_protection, new_conn_state->content_protection); + + if (old_crtc_state) + pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", + old_crtc_state->enable, + old_crtc_state->active, + old_crtc_state->mode_changed, + old_crtc_state->active_changed, + old_crtc_state->connectors_changed); + + if (new_crtc_state) + pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", + new_crtc_state->enable, + new_crtc_state->active, + new_crtc_state->mode_changed, + new_crtc_state->active_changed, + new_crtc_state->connectors_changed); + + /* hdcp content type change */ + if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type && + new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; + pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__); return true; } - /* CP is being re enabled, ignore this - * - * Handles: ENABLED -> DESIRED - */ - if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && - state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { - state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; + /* CP is being re enabled, ignore this */ + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { + if (new_crtc_state && new_crtc_state->mode_changed) { + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; + pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__); + return true; + }; + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; + pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__); return false; } @@ -7429,9 +7457,9 @@ static bool is_content_protection_different(struct drm_connector_state *state, * * Handles: UNDESIRED -> ENABLED */ - if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && - state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) - state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; + if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) + new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; /* Stream removed and re-enabled * @@ -7441,10 +7469,12 @@ static bool is_content_protection_different(struct drm_connector_state *state, * * Handles: DESIRED -> DESIRED (Special case) */ - if (!(old_state->crtc && old_state->crtc->enabled) && - state->crtc && state->crtc->enabled && + if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) && + new_conn_state->crtc && new_conn_state->crtc->enabled && connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { dm_con_state->update_hdcp = false; + pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n", + __func__); return true; } @@ -7456,35 +7486,42 @@ static bool is_content_protection_different(struct drm_connector_state *state, * * Handles: DESIRED -> DESIRED (Special case) */ - if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && - connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { + if (dm_con_state->update_hdcp && + new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && + connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { dm_con_state->update_hdcp = false; + pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n", + __func__); return true; } - /* - * Handles: UNDESIRED -> UNDESIRED - * DESIRED -> DESIRED - * ENABLED -> ENABLED - */ - if (old_state->content_protection == state->content_protection) + if (old_conn_state->content_protection == new_conn_state->content_protection) { + if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) { + if (new_crtc_state && new_crtc_state->mode_changed) { + pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n", + __func__); + return true; + }; + pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n", + __func__); + return false; + }; + + pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__); return false; + } - /* - * Handles: UNDESIRED -> DESIRED - * DESIRED -> UNDESIRED - * ENABLED -> UNDESIRED - */ - if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) + if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) { + pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n", + __func__); return true; + } - /* - * Handles: DESIRED -> ENABLED - */ + pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__); return false; } - #endif + static void remove_stream(struct amdgpu_device *adev, struct amdgpu_crtc *acrtc, struct dc_stream_state *stream) @@ -8339,10 +8376,67 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - new_crtc_state = NULL; + if (!adev->dm.hdcp_workqueue) + continue; - if (acrtc) + pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i); + + if (!connector) + continue; + + pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", + connector->index, connector->status, connector->dpms); + pr_debug("[HDCP_DM] state protection old: %x new: %x\n", + old_con_state->content_protection, new_con_state->content_protection); + + if (aconnector->dc_sink) { + if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL && + aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) { + pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n", + aconnector->dc_sink->edid_caps.display_name); + } + } + + new_crtc_state = NULL; + old_crtc_state = NULL; + + if (acrtc) { new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); + old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); + } + + if (old_crtc_state) + pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", + old_crtc_state->enable, + old_crtc_state->active, + old_crtc_state->mode_changed, + old_crtc_state->active_changed, + old_crtc_state->connectors_changed); + + if (new_crtc_state) + pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", + new_crtc_state->enable, + new_crtc_state->active, + new_crtc_state->mode_changed, + new_crtc_state->active_changed, + new_crtc_state->connectors_changed); + } + + for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { + struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + + if (!adev->dm.hdcp_workqueue) + continue; + + new_crtc_state = NULL; + old_crtc_state = NULL; + + if (acrtc) { + new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); + old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); + } dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); @@ -8354,11 +8448,44 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) continue; } - if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) + if (is_content_protection_different(new_crtc_state, old_crtc_state, new_con_state, + old_con_state, connector, adev->dm.hdcp_workqueue)) { + /* when display is unplugged from mst hub, connctor will + * be destroyed within dm_dp_mst_connector_destroy. connector + * hdcp perperties, like type, undesired, desired, enabled, + * will be lost. So, save hdcp properties into hdcp_work within + * amdgpu_dm_atomic_commit_tail. if the same display is + * plugged back with same display index, its hdcp properties + * will be retrieved from hdcp_work within dm_dp_mst_get_modes + */ + + bool enable_encryption = false; + + if (new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) + enable_encryption = true; + + if (aconnector->dc_link && aconnector->dc_sink && + aconnector->dc_link->type == dc_connection_mst_branch) { + struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; + struct hdcp_workqueue *hdcp_w = + &hdcp_work[aconnector->dc_link->link_index]; + + hdcp_w->hdcp_content_type[connector->index] = + new_con_state->hdcp_content_type; + hdcp_w->content_protection[connector->index] = + new_con_state->content_protection; + } + + if (new_crtc_state && new_crtc_state->mode_changed && + new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) + enable_encryption = true; + + DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption); + hdcp_update_display( adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, - new_con_state->hdcp_content_type, - new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED); + new_con_state->hdcp_content_type, enable_encryption); + } } #endif diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h index 8b6db2328..cff7ffa96 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h @@ -52,6 +52,20 @@ struct hdcp_workqueue { struct mod_hdcp_link link; enum mod_hdcp_encryption_status encryption_status; + + /* when display is unplugged from mst hub, connctor will be + * destroyed within dm_dp_mst_connector_destroy. connector + * hdcp perperties, like type, undesired, desired, enabled, + * will be lost. So, save hdcp properties into hdcp_work within + * amdgpu_dm_atomic_commit_tail. if the same display is + * plugged back with same display index, its hdcp properties + * will be retrieved from hdcp_work within dm_dp_mst_get_modes + */ + /* un-desired, desired, enabled */ + unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX]; + /* hdcp1.x, hdcp2.x */ + unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX]; + uint8_t max_link; uint8_t *srm; diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d07e1053b..a9ddff774 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -32,6 +32,10 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_mst_types.h" +#ifdef CONFIG_DRM_AMD_DC_HDCP +#include "amdgpu_dm_hdcp.h" +#endif + #include "dc.h" #include "dm_helpers.h" @@ -363,6 +367,32 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) /* dc_link_add_remote_sink returns a new reference */ aconnector->dc_sink = dc_sink; + /* when display is unplugged from mst hub, connctor will be + * destroyed within dm_dp_mst_connector_destroy. connector + * hdcp perperties, like type, undesired, desired, enabled, + * will be lost. So, save hdcp properties into hdcp_work within + * amdgpu_dm_atomic_commit_tail. if the same display is + * plugged back with same display index, its hdcp properties + * will be retrieved from hdcp_work within dm_dp_mst_get_modes + */ +#ifdef CONFIG_DRM_AMD_DC_HDCP + if (aconnector->dc_sink && connector->state) { + struct drm_device *dev = connector->dev; + struct amdgpu_device *adev = drm_to_adev(dev); + + if (adev->dm.hdcp_workqueue) { + struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; + struct hdcp_workqueue *hdcp_w = + &hdcp_work[aconnector->dc_link->link_index]; + + connector->state->hdcp_content_type = + hdcp_w->hdcp_content_type[connector->index]; + connector->state->content_protection = + hdcp_w->content_protection[connector->index]; + } + } +#endif + if (aconnector->dc_sink) { amdgpu_dm_update_freesync_caps( connector, aconnector->edid); diff --git a/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h b/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h index 915a20461..893c0809c 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -230,7 +230,8 @@ type DTBCLK_P2_SRC_SEL;\ type DTBCLK_P2_EN;\ type DTBCLK_P3_SRC_SEL;\ - type DTBCLK_P3_EN; + type DTBCLK_P3_EN;\ + type DENTIST_DISPCLK_CHG_DONE; struct dccg_shift { DCCG_REG_FIELD_LIST(uint8_t) diff --git a/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_dccg.c b/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_dccg.c index 7d2b98250..cef32a1f9 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -47,6 +47,14 @@ void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + if (dccg->dpp_clock_gated[dpp_inst]) { + /* + * Do not update the DPPCLK DTO if the clock is stopped. + * It is treated the same as if the pipe itself were in PG. + */ + return; + } + if (dccg->ref_dppclk && req_dppclk) { int ref_dppclk = dccg->ref_dppclk; int modulo, phase; diff --git a/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_dccg.c b/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_dccg.c index 85ea33343..b74705c1c 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_dccg.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_dccg.c @@ -296,6 +296,9 @@ static void dccg314_dpp_root_clock_control( { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + if (dccg->dpp_clock_gated[dpp_inst] != clock_on) + return; + if (clock_on) { /* turn off the DTO and leave phase/modulo at max */ REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0); @@ -309,6 +312,8 @@ static void dccg314_dpp_root_clock_control( DPPCLK0_DTO_PHASE, 0, DPPCLK0_DTO_MODULO, 1); } + + dccg->dpp_clock_gated[dpp_inst] = !clock_on; } static const struct dccg_funcs dccg314_funcs = { diff --git a/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_resource.c b/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_resource.c index b7782433c..503ab45b4 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -920,6 +920,22 @@ static const struct dc_debug_options debug_defaults_drv = { .afmt = true, } }, + + .root_clock_optimization = { + .bits = { + .dpp = true, + .dsc = false, + .hdmistream = false, + .hdmichar = false, + .dpstream = false, + .symclk32_se = false, + .symclk32_le = false, + .symclk_fe = false, + .physymclk = false, + .dpiasymclk = false, + } + }, + .seamless_boot_odm_combine = true }; @@ -1917,6 +1933,10 @@ static bool dcn314_resource_construct( dc->debug = debug_defaults_drv; else dc->debug = debug_defaults_diags; + + /* Disable root clock optimization */ + dc->debug.root_clock_optimization.u32All = 0; + // Init the vm_helper if (dc->vm_helper) vm_helper_init(dc->vm_helper, 16); diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c index 3fb4bcc34..ffbb739d8 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -42,6 +42,20 @@ #define DC_LOGGER \ dccg->ctx->logger +/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV + * without the probability of causing a DIG FIFO error. + */ +static void dccg32_wait_for_dentist_change_done( + struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL); + + REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); +} + static void dccg32_get_pixel_rate_div( struct dccg *dccg, uint32_t otg_inst, @@ -110,21 +124,29 @@ static void dccg32_set_pixel_rate_div( REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG0_PIXEL_RATE_DIVK1, k1, OTG0_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 1: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG1_PIXEL_RATE_DIVK1, k1, OTG1_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 2: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG2_PIXEL_RATE_DIVK1, k1, OTG2_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 3: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK1, k1, OTG3_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; default: BREAK_TO_DEBUGGER(); diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h index 1c46fad09..fc3c9c650 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h @@ -147,7 +147,8 @@ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\ - DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh) + DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\ + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) struct dccg *dccg32_create( diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 601b65483..fa075789c 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1177,7 +1177,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign *k2_div = PIXEL_RATE_DIV_BY_2; else *k2_div = PIXEL_RATE_DIV_BY_4; - } else if (dc_is_dp_signal(stream->signal)) { + } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { if (two_pix_per_container) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_2; diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h index 026cf13d2..03cdfb557 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -1272,7 +1272,8 @@ unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans); DCCG_SRII(PHASE, DTBCLK_DTO, 0), DCCG_SRII(PHASE, DTBCLK_DTO, 1), \ DCCG_SRII(PHASE, DTBCLK_DTO, 2), DCCG_SRII(PHASE, DTBCLK_DTO, 3), \ SR(DCCG_AUDIO_DTBCLK_DTO_MODULO), SR(DCCG_AUDIO_DTBCLK_DTO_PHASE), \ - SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), SR(DCCG_AUDIO_DTO_SOURCE) \ + SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), \ + SR(DCCG_AUDIO_DTO_SOURCE), SR(DENTIST_DISPCLK_CNTL) \ ) /* VMID */ diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c index 2bb768413..19f556572 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -808,7 +808,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman v->SwathHeightC[k], TWait, (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || - v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ? + v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, /* Output */ &v->DSTXAfterScaler[k], @@ -3289,7 +3289,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->swath_width_chroma_ub_this_state[k], v->SwathHeightYThisState[k], v->SwathHeightCThisState[k], v->TWait, - (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ? + (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, /* Output */ diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h index e92eee2c6..a475775bc 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h @@ -52,7 +52,7 @@ #define BPP_BLENDED_PIPE 0xffffffff #define MEM_STROBE_FREQ_MHZ 1600 -#define MIN_DCFCLK_FREQ_MHZ 200 +#define DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ 300 #define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0 struct display_mode_lib; diff --git a/sys/dev/pci/drm/amd/display/dc/inc/hw/dccg.h b/sys/dev/pci/drm/amd/display/dc/inc/hw/dccg.h index ad6acd1b3..9651cccb0 100644 --- a/sys/dev/pci/drm/amd/display/dc/inc/hw/dccg.h +++ b/sys/dev/pci/drm/amd/display/dc/inc/hw/dccg.h @@ -68,6 +68,7 @@ struct dccg { const struct dccg_funcs *funcs; int pipe_dppclk_khz[MAX_PIPES]; int ref_dppclk; + bool dpp_clock_gated[MAX_PIPES]; //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ //int audio_dtbclk_khz;/* TODO needs to be removed */ //int ref_dtbclk_khz;/* TODO needs to be removed */ diff --git a/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c b/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c index f68365e8a..828806828 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1562,9 +1562,9 @@ static int smu_disable_dpms(struct smu_context *smu) /* * For SMU 13.0.4/11, PMFW will handle the features disablement properly - * for gpu reset case. Driver involvement is unnecessary. + * for gpu reset and S0i3 cases. Driver involvement is unnecessary. */ - if (amdgpu_in_reset(adev)) { + if (amdgpu_in_reset(adev) || adev->in_s0ix) { switch (adev->ip_versions[MP1_HWIP][0]) { case IP_VERSION(13, 0, 4): case IP_VERSION(13, 0, 11): diff --git a/sys/dev/pci/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/sys/dev/pci/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index a42dc0202..60deb116c 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -588,7 +588,9 @@ err0_out: return -ENOMEM; } -static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu) +static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu, + bool use_metrics_v3, + bool use_metrics_v2) { struct smu_table_context *smu_table= &smu->smu_table; SmuMetricsExternal_t *metrics_ext = @@ -596,13 +598,11 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s uint32_t throttler_status = 0; int i; - if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4900)) { + if (use_metrics_v3) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V3.ThrottlingPercentage[i] ? 1U << i : 0); - } else if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4300)) { + } else if (use_metrics_v2) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V2.ThrottlingPercentage[i] ? 1U << i : 0); @@ -864,7 +864,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, metrics->TemperatureVrSoc) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_THROTTLER_STATUS: - *value = sienna_cichlid_get_throttler_status_locked(smu); + *value = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); break; case METRICS_CURR_FANSPEED: *value = use_metrics_v3 ? metrics_v3->CurrFanSpeed : @@ -4019,7 +4019,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_dclk1 = use_metrics_v3 ? metrics_v3->CurrClock[PPCLK_DCLK_1] : use_metrics_v2 ? metrics_v2->CurrClock[PPCLK_DCLK_1] : metrics->CurrClock[PPCLK_DCLK_1]; - gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu); + gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); gpu_metrics->indep_throttle_status = smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status, sienna_cichlid_throttler_map); diff --git a/sys/dev/pci/drm/i915/display/intel_sdvo.c b/sys/dev/pci/drm/i915/display/intel_sdvo.c index 23d40ac80..fa7b47b37 100644 --- a/sys/dev/pci/drm/i915/display/intel_sdvo.c +++ b/sys/dev/pci/drm/i915/display/intel_sdvo.c @@ -2727,7 +2727,7 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) __drm_atomic_helper_connector_reset(&sdvo_connector->base.base, &conn_state->base.base); - INIT_LIST_HEAD(&sdvo_connector->base.panel.fixed_modes); + intel_panel_init_alloc(&sdvo_connector->base); return sdvo_connector; } diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 4c2175e8c..22b2d6043 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.114 2023/08/22 13:46:20 jsg Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.115 2023/08/23 01:55:45 cheloha Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -103,6 +103,9 @@ initclocks(void) profclock_period = 1000000000 / profhz; inittimecounter(); + + /* Start dispatching clock interrupts on the primary CPU. */ + cpu_startclock(); } /* diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 65e724575..9a095f7d2 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systm.h,v 1.164 2023/08/05 20:07:56 cheloha Exp $ */ +/* $OpenBSD: systm.h,v 1.165 2023/08/23 01:55:45 cheloha Exp $ */ /* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */ /*- @@ -243,6 +243,7 @@ void initclocks(void); void inittodr(time_t); void resettodr(void); void cpu_initclocks(void); +void cpu_startclock(void); void startprofclock(struct process *); void stopprofclock(struct process *); diff --git a/usr.bin/tmux/cmd-run-shell.c b/usr.bin/tmux/cmd-run-shell.c index 8b9ec1547..d962eedd2 100644 --- a/usr.bin/tmux/cmd-run-shell.c +++ b/usr.bin/tmux/cmd-run-shell.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-run-shell.c,v 1.84 2022/06/02 21:19:32 nicm Exp $ */ +/* $OpenBSD: cmd-run-shell.c,v 1.85 2023/08/23 08:40:25 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha @@ -44,8 +44,9 @@ const struct cmd_entry cmd_run_shell_entry = { .name = "run-shell", .alias = "run", - .args = { "bd:Ct:", 0, 1, cmd_run_shell_args_parse }, - .usage = "[-bC] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", + .args = { "bd:Ct:c:", 0, 2, cmd_run_shell_args_parse }, + .usage = "[-bC] [-c start-directory] [-d delay] " CMD_TARGET_PANE_USAGE + " [shell-command]", .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, @@ -103,6 +104,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); struct cmd_run_shell_data *cdata; + struct client *c = cmdq_get_client(item); struct client *tc = cmdq_get_target_client(item); struct session *s = target->s; struct window_pane *wp = target->wp; @@ -137,7 +139,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) cdata->wp_id = -1; if (wait) { - cdata->client = cmdq_get_client(item); + cdata->client = c; cdata->item = item; } else { cdata->client = tc; @@ -145,8 +147,10 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) } if (cdata->client != NULL) cdata->client->references++; - - cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); + if (args_has(args, 'c')) + cdata->cwd = xstrdup(args_get(args, 'c')); + else + cdata->cwd = xstrdup(server_client_get_cwd(c, s)); cdata->s = s; if (s != NULL) diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index a00a340f4..41826662b 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.219 2023/08/08 08:21:29 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.220 2023/08/23 08:30:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2248,10 +2248,13 @@ input_dcs_dispatch(struct input_ctx *ictx) if (wp == NULL) return (0); - if (ictx->flags & INPUT_DISCARD) + if (ictx->flags & INPUT_DISCARD) { + log_debug("%s: %zu bytes (discard)", __func__, len); return (0); - allow_passthrough = options_get_number(wp->options, - "allow-passthrough"); + } + log_debug("%s: %zu bytes", __func__, len); + + allow_passthrough = options_get_number(wp->options, "allow-passthrough"); if (!allow_passthrough) return (0); log_debug("%s: \"%s\"", __func__, buf); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 34ee4037b..e3a6d843f 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.928 2023/08/17 14:10:28 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.929 2023/08/23 08:40:25 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 17 2023 $ +.Dd $Mdocdate: August 23 2023 $ .Dt TMUX 1 .Os .Sh NAME @@ -6639,6 +6639,7 @@ option. .Tg run .It Xo Ic run-shell .Op Fl bC +.Op Fl c Ar start-directory .Op Fl d Ar delay .Op Fl t Ar target-pane .Op Ar shell-command @@ -6666,6 +6667,10 @@ waits for .Ar delay seconds before starting the command. If +.Fl c +is given, the current working directory is set to +.Ar start-directory . +If .Fl C is not given, any output to stdout is displayed in view mode (in the pane specified by