diff --git a/lib/libcrypto/asn1/asn1_item.c b/lib/libcrypto/asn1/asn1_item.c index 1bdb743a9..3b02b6664 100644 --- a/lib/libcrypto/asn1/asn1_item.c +++ b/lib/libcrypto/asn1/asn1_item.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_item.c,v 1.7 2023/06/13 23:31:53 tb Exp $ */ +/* $OpenBSD: asn1_item.c,v 1.14 2023/06/15 13:58:56 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -233,41 +233,49 @@ ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, { const EVP_MD *type; EVP_PKEY *pkey; - unsigned char *buf_in = NULL, *buf_out = NULL; - size_t buf_out_len = 0; - int in_len = 0, out_len = 0; + unsigned char *in = NULL, *out = NULL; + size_t out_len = 0; + int in_len = 0; int signid, paramtype; int rv = 2; int ret = 0; - type = EVP_MD_CTX_md(ctx); - pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); - - if (!type || !pkey) { + if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx)) == NULL) { ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } - if (pkey->ameth->item_sign) { + if (pkey->ameth == NULL) { + ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + + if (pkey->ameth->item_sign != NULL) { rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); - if (rv == 1) + if (rv == 1) { out_len = signature->length; + goto done; + } /* Return value meanings: * <=0: error. * 1: method does everything. * 2: carry on as normal. * 3: ASN1 method sets algorithm identifiers: just sign. */ - if (rv <= 0) + if (rv <= 0) { ASN1error(ERR_R_EVP_LIB); - if (rv <= 1) goto err; + } } if (rv == 2) { - if (!pkey->ameth || - !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), + if ((type = EVP_MD_CTX_md(ctx)) == NULL) { + ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey->ameth->pkey_id)) { ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; @@ -287,46 +295,43 @@ ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, } - if ((in_len = ASN1_item_i2d(asn, &buf_in, it)) <= 0) { + if ((in_len = ASN1_item_i2d(asn, &in, it)) <= 0) { in_len = 0; goto err; } - if ((out_len = EVP_PKEY_size(pkey)) <= 0) { - out_len = 0; + if (!EVP_DigestSign(ctx, NULL, &out_len, in, in_len)) { + ASN1error(ERR_R_EVP_LIB); goto err; } - - if ((buf_out = malloc(out_len)) == NULL) { + if ((out = calloc(1, out_len)) == NULL) { ASN1error(ERR_R_MALLOC_FAILURE); goto err; } - - buf_out_len = out_len; - if (!EVP_DigestSignUpdate(ctx, buf_in, in_len) || - !EVP_DigestSignFinal(ctx, buf_out, &buf_out_len)) { + if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) { ASN1error(ERR_R_EVP_LIB); goto err; } - if (buf_out_len > INT_MAX) { + if (out_len > INT_MAX) { ASN1error(ASN1_R_TOO_LONG); goto err; } - ASN1_STRING_set0(signature, buf_out, (int)buf_out_len); - buf_out = NULL; + ASN1_STRING_set0(signature, out, out_len); + out = NULL; if (!asn1_abs_set_unused_bits(signature, 0)) { ASN1error(ERR_R_ASN1_LIB); goto err; } - ret = (int)buf_out_len; + done: + ret = out_len; err: EVP_MD_CTX_cleanup(ctx); - freezero(buf_in, in_len); - freezero(buf_out, out_len); + freezero(in, in_len); + freezero(out, out_len); return ret; } @@ -336,18 +341,17 @@ ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX ctx; - unsigned char *buf_in = NULL; - int ret = -1, inl; - + unsigned char *in = NULL; int mdnid, pknid; + int in_len = 0; + int ret = -1; - if (!pkey) { + if (pkey == NULL) { ASN1error(ERR_R_PASSED_NULL_PARAMETER); return -1; } - if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) - { + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT); return -1; } @@ -395,35 +399,26 @@ ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, } - inl = ASN1_item_i2d(asn, &buf_in, it); - - if (buf_in == NULL) { + if ((in_len = ASN1_item_i2d(asn, &in, it)) <= 0) { ASN1error(ERR_R_MALLOC_FAILURE); + in_len = 0; goto err; } - if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { + if (EVP_DigestVerify(&ctx, signature->data, signature->length, + in, in_len) <= 0) { ASN1error(ERR_R_EVP_LIB); ret = 0; goto err; } - freezero(buf_in, (unsigned int)inl); - - if (EVP_DigestVerifyFinal(&ctx, signature->data, - (size_t)signature->length) <= 0) { - ASN1error(ERR_R_EVP_LIB); - ret = 0; - goto err; - } - /* we don't need to zero the 'ctx' because we just checked - * public information */ - /* memset(&ctx,0,sizeof(ctx)); */ ret = 1; err: EVP_MD_CTX_cleanup(&ctx); - return (ret); + freezero(in, in_len); + + return ret; } #define HEADER_SIZE 8 diff --git a/lib/libcrypto/objects/obj_xref.h b/lib/libcrypto/objects/obj_xref.h index cffd00699..1003030fc 100644 --- a/lib/libcrypto/objects/obj_xref.h +++ b/lib/libcrypto/objects/obj_xref.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obj_xref.h,v 1.5 2021/05/12 10:24:39 inoguchi Exp $ */ +/* $OpenBSD: obj_xref.h,v 1.6 2023/06/15 16:59:54 tb Exp $ */ /* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ __BEGIN_HIDDEN_DECLS @@ -44,6 +44,7 @@ static const nid_triple sigoid_srt[] = {NID_rsassaPss, NID_undef, NID_rsaEncryption}, {NID_id_tc26_signwithdigest_gost3410_2012_256, NID_id_tc26_gost3411_2012_256, NID_id_GostR3410_2001}, {NID_id_tc26_signwithdigest_gost3410_2012_512, NID_id_tc26_gost3411_2012_512, NID_id_GostR3410_2001}, + {NID_Ed25519, NID_undef, NID_Ed25519}, {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf}, {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf}, {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf}, @@ -59,8 +60,9 @@ static const nid_triple sigoid_srt[] = static const nid_triple * const sigoid_srt_xref[] = { &sigoid_srt[29], - &sigoid_srt[17], &sigoid_srt[18], + &sigoid_srt[17], + &sigoid_srt[32], &sigoid_srt[0], &sigoid_srt[1], &sigoid_srt[7], @@ -71,29 +73,29 @@ static const nid_triple * const sigoid_srt_xref[] = &sigoid_srt[5], &sigoid_srt[8], &sigoid_srt[12], - &sigoid_srt[32], - &sigoid_srt[37], + &sigoid_srt[33], + &sigoid_srt[38], &sigoid_srt[6], &sigoid_srt[10], &sigoid_srt[11], &sigoid_srt[13], &sigoid_srt[24], &sigoid_srt[20], - &sigoid_srt[34], - &sigoid_srt[39], - &sigoid_srt[14], - &sigoid_srt[21], &sigoid_srt[35], &sigoid_srt[40], - &sigoid_srt[15], - &sigoid_srt[22], + &sigoid_srt[14], + &sigoid_srt[21], &sigoid_srt[36], &sigoid_srt[41], + &sigoid_srt[15], + &sigoid_srt[22], + &sigoid_srt[37], + &sigoid_srt[42], &sigoid_srt[16], &sigoid_srt[23], &sigoid_srt[19], - &sigoid_srt[33], - &sigoid_srt[38], + &sigoid_srt[34], + &sigoid_srt[39], &sigoid_srt[25], &sigoid_srt[26], &sigoid_srt[27], diff --git a/lib/libcrypto/objects/obj_xref.txt b/lib/libcrypto/objects/obj_xref.txt index e874611a4..955977fc2 100644 --- a/lib/libcrypto/objects/obj_xref.txt +++ b/lib/libcrypto/objects/obj_xref.txt @@ -1,6 +1,8 @@ # OID cross reference table. # Links signatures OIDs to their corresponding public key algorithms -# and digests. +# and digests. The digest "undef" indicates the public key's ASN.1 +# method should handle AlgorithmIdentifiers and (at least part of) the +# message digest explicitly. md2WithRSAEncryption md2 rsaEncryption md5WithRSAEncryption md5 rsaEncryption @@ -14,10 +16,11 @@ sha224WithRSAEncryption sha224 rsaEncryption mdc2WithRSA mdc2 rsaEncryption ripemd160WithRSA ripemd160 rsaEncryption # For PSS the digest algorithm can vary and depends on the included -# AlgorithmIdentifier. The digest "undef" indicates the public key -# method should handle this explicitly. +# AlgorithmIdentifier. rsassaPss undef rsaEncryption +Ed25519 undef Ed25519 + # Alternative deprecated OIDs. By using the older "rsa" OID this # type will be recognized by not normally used. diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c index aacff4894..df5255c4a 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gfx.c @@ -685,9 +685,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *r if (r) return r; - r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0); - if (r) - goto late_fini; + if (adev->gfx.cp_ecc_error_irq.funcs) { + r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0); + if (r) + goto late_fini; + } } else { amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0); } diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.c index c3a30774f..9bbd7cd61 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.c @@ -1432,13 +1432,31 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe) struct amdgpu_firmware_info *info; char ucode_prefix[30]; char fw_name[40]; + bool need_retry = false; int r; - amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin", - ucode_prefix, - pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1"); + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) { + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin", + ucode_prefix, + pipe == AMDGPU_MES_SCHED_PIPE ? "_2" : "1"); + need_retry = true; + } else { + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin", + ucode_prefix, + pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1"); + } + r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe], fw_name); + if (r && need_retry && pipe == AMDGPU_MES_SCHED_PIPE) { + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin", + ucode_prefix); + DRM_INFO("try to fall back to %s\n", fw_name); + r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe], + fw_name); + } + if (r) goto out; diff --git a/sys/dev/pci/drm/amd/amdgpu/gfx_v10_0.c b/sys/dev/pci/drm/amd/amdgpu/gfx_v10_0.c index f03de718c..634a71a8c 100644 --- a/sys/dev/pci/drm/amd/amdgpu/gfx_v10_0.c +++ b/sys/dev/pci/drm/amd/amdgpu/gfx_v10_0.c @@ -8236,8 +8236,14 @@ static int gfx_v10_0_set_powergating_state(void *handle, case IP_VERSION(10, 3, 3): case IP_VERSION(10, 3, 6): case IP_VERSION(10, 3, 7): + if (!enable) + amdgpu_gfx_off_ctrl(adev, false); + gfx_v10_cntl_pg(adev, enable); - amdgpu_gfx_off_ctrl(adev, enable); + + if (enable) + amdgpu_gfx_off_ctrl(adev, true); + break; default: break; diff --git a/sys/dev/pci/drm/amd/amdgpu/gfx_v11_0.c b/sys/dev/pci/drm/amd/amdgpu/gfx_v11_0.c index 5c2050dac..3ebb51ca9 100644 --- a/sys/dev/pci/drm/amd/amdgpu/gfx_v11_0.c +++ b/sys/dev/pci/drm/amd/amdgpu/gfx_v11_0.c @@ -4641,13 +4641,29 @@ static int gfx_v11_0_post_soft_reset(void *handle) static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev) { uint64_t clock; + uint64_t clock_counter_lo, clock_counter_hi_pre, clock_counter_hi_after; + + if (amdgpu_sriov_vf(adev)) { + amdgpu_gfx_off_ctrl(adev, false); + mutex_lock(&adev->gfx.gpu_clock_mutex); + clock_counter_hi_pre = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_HI); + clock_counter_lo = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_LO); + clock_counter_hi_after = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_HI); + if (clock_counter_hi_pre != clock_counter_hi_after) + clock_counter_lo = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_LO); + mutex_unlock(&adev->gfx.gpu_clock_mutex); + amdgpu_gfx_off_ctrl(adev, true); + } else { + preempt_disable(); + clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); + clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); + if (clock_counter_hi_pre != clock_counter_hi_after) + clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); + preempt_enable(); + } + clock = clock_counter_lo | (clock_counter_hi_after << 32ULL); - amdgpu_gfx_off_ctrl(adev, false); - mutex_lock(&adev->gfx.gpu_clock_mutex); - clock = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER) | - ((uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER) << 32ULL); - mutex_unlock(&adev->gfx.gpu_clock_mutex); - amdgpu_gfx_off_ctrl(adev, true); return clock; } @@ -5085,8 +5101,14 @@ static int gfx_v11_0_set_powergating_state(void *handle, break; case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 4): + if (!enable) + amdgpu_gfx_off_ctrl(adev, false); + gfx_v11_cntl_pg(adev, enable); - amdgpu_gfx_off_ctrl(adev, enable); + + if (enable) + amdgpu_gfx_off_ctrl(adev, true); + break; default: break; diff --git a/sys/dev/pci/drm/amd/amdgpu/gmc_v11_0.c b/sys/dev/pci/drm/amd/amdgpu/gmc_v11_0.c index 2252e10d3..47b564058 100644 --- a/sys/dev/pci/drm/amd/amdgpu/gmc_v11_0.c +++ b/sys/dev/pci/drm/amd/amdgpu/gmc_v11_0.c @@ -31,6 +31,8 @@ #include "umc_v8_10.h" #include "athub/athub_3_0_0_sh_mask.h" #include "athub/athub_3_0_0_offset.h" +#include "dcn/dcn_3_2_0_offset.h" +#include "dcn/dcn_3_2_0_sh_mask.h" #include "oss/osssys_6_0_0_offset.h" #include "ivsrcid/vmc/irqsrcs_vmc_1_0.h" #include "navi10_enum.h" @@ -523,7 +525,24 @@ static void gmc_v11_0_get_vm_pte(struct amdgpu_device *adev, static unsigned gmc_v11_0_get_vbios_fb_size(struct amdgpu_device *adev) { - return 0; + u32 d1vga_control = RREG32_SOC15(DCE, 0, regD1VGA_CONTROL); + unsigned size; + + if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) { + size = AMDGPU_VBIOS_VGA_ALLOCATION; + } else { + u32 viewport; + u32 pitch; + + viewport = RREG32_SOC15(DCE, 0, regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION); + pitch = RREG32_SOC15(DCE, 0, regHUBPREQ0_DCSURF_SURFACE_PITCH); + size = (REG_GET_FIELD(viewport, + HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) * + REG_GET_FIELD(pitch, HUBPREQ0_DCSURF_SURFACE_PITCH, PITCH) * + 4); + } + + return size; } static const struct amdgpu_gmc_funcs gmc_v11_0_gmc_funcs = { diff --git a/sys/dev/pci/drm/amd/amdgpu/mes_v11_0.c b/sys/dev/pci/drm/amd/amdgpu/mes_v11_0.c index 6bc4ada3a..d1004f77b 100644 --- a/sys/dev/pci/drm/amd/amdgpu/mes_v11_0.c +++ b/sys/dev/pci/drm/amd/amdgpu/mes_v11_0.c @@ -33,13 +33,20 @@ #include "mes_v11_api_def.h" MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes_2.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes_2.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes_2.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes_2.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes_2.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes1.bin"); static int mes_v11_0_hw_fini(void *handle); static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev); diff --git a/sys/dev/pci/drm/amd/amdgpu/sdma_v4_0.c b/sys/dev/pci/drm/amd/amdgpu/sdma_v4_0.c index caa8a2118..ec8a202b6 100644 --- a/sys/dev/pci/drm/amd/amdgpu/sdma_v4_0.c +++ b/sys/dev/pci/drm/amd/amdgpu/sdma_v4_0.c @@ -1908,7 +1908,7 @@ static int sdma_v4_0_sw_fini(void *handle) amdgpu_ring_fini(&adev->sdma.instance[i].page); } - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 0) || + if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) || adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) amdgpu_sdma_destroy_inst_ctx(adev, true); else diff --git a/sys/dev/pci/drm/amd/display/dc/bios/bios_parser2.c b/sys/dev/pci/drm/amd/display/dc/bios/bios_parser2.c index 074e70a5c..e507d2e14 100644 --- a/sys/dev/pci/drm/amd/display/dc/bios/bios_parser2.c +++ b/sys/dev/pci/drm/amd/display/dc/bios/bios_parser2.c @@ -516,11 +516,8 @@ static enum bp_result get_gpio_i2c_info( info->i2c_slave_address = record->i2c_slave_addr; /* TODO: check how to get register offset for en, Y, etc. */ - info->gpio_info.clk_a_register_index = - le16_to_cpu( - header->gpio_pin[table_index].data_a_reg_index); - info->gpio_info.clk_a_shift = - header->gpio_pin[table_index].gpio_bitshift; + info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index); + info->gpio_info.clk_a_shift = pin->gpio_bitshift; return BP_RESULT_OK; } diff --git a/sys/dev/pci/drm/amd/display/dc/dc_dmub_srv.c b/sys/dev/pci/drm/amd/display/dc/dc_dmub_srv.c index 0541e87e4..a461e9463 100644 --- a/sys/dev/pci/drm/amd/display/dc/dc_dmub_srv.c +++ b/sys/dev/pci/drm/amd/display/dc/dc_dmub_srv.c @@ -764,7 +764,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, !pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream->mall_stream_config.type == SUBVP_MAIN) { populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); - } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) { + } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE && + !pipe->top_pipe && !pipe->prev_odm_pipe) { // Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where // we run through DML without calculating "natural" P-state support populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); diff --git a/sys/dev/pci/drm/amd/display/dc/dce/dce_transform.c b/sys/dev/pci/drm/amd/display/dc/dce/dce_transform.c index d9fd4ec60..670d5ab9d 100644 --- a/sys/dev/pci/drm/amd/display/dc/dce/dce_transform.c +++ b/sys/dev/pci/drm/amd/display/dc/dce/dce_transform.c @@ -1009,7 +1009,7 @@ static void dce_transform_set_pixel_storage_depth( color_depth = COLOR_DEPTH_101010; pixel_depth = 0; expan_mode = 1; - BREAK_TO_DEBUGGER(); + DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth); break; } @@ -1023,8 +1023,7 @@ static void dce_transform_set_pixel_storage_depth( if (!(xfm_dce->lb_pixel_depth_supported & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ - DC_LOG_WARNING("%s: Capability not supported", - __func__); + DC_LOG_DC("%s: Capability not supported", __func__); } } diff --git a/sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_hwseq.c index c20e9f76f..a1b312483 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -629,7 +629,8 @@ void dcn30_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + //if softmax is enabled then hardmax will be set by a different call + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) diff --git a/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_hwseq.c index bdf101547..d4ee533de 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -284,7 +284,7 @@ void dcn31_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) 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 6ff88a81d..74530e2e7 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 @@ -970,7 +970,7 @@ void dcn32_init_hw(struct dc *dc) if (dc->clk_mgr->funcs->notify_wm_ranges) dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); - if (dc->clk_mgr->funcs->set_hard_max_memclk) + if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled) dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); if (dc->res_pool->hubbub->funcs->force_pstate_change_control) diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 1e9b157cf..65fb78331 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -4868,7 +4868,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NoUrgentLatencyHidingPre[k]); } diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c index b612edb14..cf8f3d690 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -4305,11 +4305,11 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->AudioSampleRate[k], v->AudioSampleLayout[k], v->ODMCombineEnablePerState[i][k]); - } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) { + } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) { if (v->DSCEnable[k] == true) { v->RequiresDSC[i][k] = true; v->LinkDSCEnable = true; - if (v->Output[k] == dm_dp) { + if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) { v->RequiresFEC[i][k] = true; } else { v->RequiresFEC[i][k] = false; @@ -4317,107 +4317,201 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } else { v->RequiresDSC[i][k] = false; v->LinkDSCEnable = false; - v->RequiresFEC[i][k] = false; + if (v->Output[k] == dm_dp2p0) { + v->RequiresFEC[i][k] = true; + } else { + v->RequiresFEC[i][k] = false; + } } - - v->Outbpp = BPP_INVALID; - if (v->PHYCLKPerState[i] >= 270.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 2700, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 5400, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 8100, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 10000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4"; - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) { - v->Outbpp = TruncToValidBPP( - 12000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4"; + if (v->Output[k] == dm_dp2p0) { + v->Outbpp = BPP_INVALID; + if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) && + v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) && + v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) && + v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true && + v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20" + } + } else { + v->Outbpp = BPP_INVALID; + if (v->PHYCLKPerState[i] >= 270.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 2700, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 5400, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 8100, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" + } } } } else { @@ -5095,7 +5189,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NotUrgentLatencyHidingPre[k]); } diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c index 4f91e6475..bf77e56c3 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -310,6 +310,10 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width)) upscaled = true; + /* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */ + if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE) + pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active; + /* * Immediate flip can be set dynamically after enabling the plane. * We need to require support for immediate flip or underflow can be diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c index 3afd3c80e..4998b211c 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c @@ -4403,11 +4403,11 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ v->AudioSampleRate[k], v->AudioSampleLayout[k], v->ODMCombineEnablePerState[i][k]); - } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) { + } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) { if (v->DSCEnable[k] == true) { v->RequiresDSC[i][k] = true; v->LinkDSCEnable = true; - if (v->Output[k] == dm_dp) { + if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) { v->RequiresFEC[i][k] = true; } else { v->RequiresFEC[i][k] = false; @@ -4415,107 +4415,201 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ } else { v->RequiresDSC[i][k] = false; v->LinkDSCEnable = false; - v->RequiresFEC[i][k] = false; + if (v->Output[k] == dm_dp2p0) { + v->RequiresFEC[i][k] = true; + } else { + v->RequiresFEC[i][k] = false; + } } - - v->Outbpp = BPP_INVALID; - if (v->PHYCLKPerState[i] >= 270.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 2700, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 5400, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 8100, - v->OutputLinkDPLanes[k], - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - // TODO: Need some other way to handle this nonsense - // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) { - v->Outbpp = TruncToValidBPP( - (1.0 - v->Downspreading / 100.0) * 10000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4"; - } - if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) { - v->Outbpp = TruncToValidBPP( - 12000, - 4, - v->HTotal[k], - v->HActive[k], - v->PixelClockBackEnd[k], - v->ForcedOutputLinkBPP[k], - v->LinkDSCEnable, - v->Output[k], - v->OutputFormat[k], - v->DSCInputBitPerComponent[k], - v->NumberOfDSCSlices[k], - v->AudioSampleRate[k], - v->AudioSampleLayout[k], - v->ODMCombineEnablePerState[i][k]); - v->OutputBppPerState[i][k] = v->Outbpp; - //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4"; + if (v->Output[k] == dm_dp2p0) { + v->Outbpp = BPP_INVALID; + if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) && + v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 10000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) && + v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 && + v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 13500, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5" + } + if (v->Outbpp == BPP_INVALID && + (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) && + v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true && + v->ForcedOutputLinkBPP[k] == 0) { + v->RequiresDSC[i][k] = true; + v->LinkDSCEnable = true; + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 20000, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + } + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20" + } + } else { + v->Outbpp = BPP_INVALID; + if (v->PHYCLKPerState[i] >= 270.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 2700, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 5400, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2" + } + if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) { + v->Outbpp = TruncToValidBPP( + (1.0 - v->Downspreading / 100.0) * 8100, + v->OutputLinkDPLanes[k], + v->HTotal[k], + v->HActive[k], + v->PixelClockBackEnd[k], + v->ForcedOutputLinkBPP[k], + v->LinkDSCEnable, + v->Output[k], + v->OutputFormat[k], + v->DSCInputBitPerComponent[k], + v->NumberOfDSCSlices[k], + v->AudioSampleRate[k], + v->AudioSampleLayout[k], + v->ODMCombineEnablePerState[i][k]); + v->OutputBppPerState[i][k] = v->Outbpp; + // TODO: Need some other way to handle this nonsense + // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3" + } } } } else { @@ -5192,7 +5286,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ v->DETBufferSizeCThisState[k], &v->UrgentBurstFactorCursorPre[k], &v->UrgentBurstFactorLumaPre[k], - &v->UrgentBurstFactorChroma[k], + &v->UrgentBurstFactorChromaPre[k], &v->NotUrgentLatencyHidingPre[k]); } 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 e02e9d4b0..2bb768413 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 @@ -3333,7 +3333,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l /* Output */ &mode_lib->vba.UrgentBurstFactorCursorPre[k], &mode_lib->vba.UrgentBurstFactorLumaPre[k], - &mode_lib->vba.UrgentBurstFactorChroma[k], + &mode_lib->vba.UrgentBurstFactorChromaPre[k], &mode_lib->vba.NotUrgentLatencyHidingPre[k]); } 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 192ab5df7..65cad0056 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/amdgpu_smu.c @@ -723,6 +723,24 @@ static int smu_late_init(void *handle) return ret; } + /* + * Explicitly notify PMFW the power mode the system in. Since + * the PMFW may boot the ASIC with a different mode. + * For those supporting ACDC switch via gpio, PMFW will + * handle the switch automatically. Driver involvement + * is unnecessary. + */ + if (!smu->dc_controlled_by_gpio) { + ret = smu_set_power_source(smu, + adev->pm.ac_power ? SMU_POWER_SOURCE_AC : + SMU_POWER_SOURCE_DC); + if (ret) { + dev_err(adev->dev, "Failed to switch to %s mode!\n", + adev->pm.ac_power ? "AC" : "DC"); + return ret; + } + } + if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 1)) || (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 3))) return 0; diff --git a/sys/dev/pci/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/sys/dev/pci/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 25f2e78d3..518fcb35d 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -3408,26 +3408,8 @@ static int navi10_post_smu_init(struct smu_context *smu) return 0; ret = navi10_run_umc_cdr_workaround(smu); - if (ret) { + if (ret) dev_err(adev->dev, "Failed to apply umc cdr workaround!\n"); - return ret; - } - - if (!smu->dc_controlled_by_gpio) { - /* - * For Navi1X, manually switch it to AC mode as PMFW - * may boot it with DC mode. - */ - ret = smu_v11_0_set_power_source(smu, - adev->pm.ac_power ? - SMU_POWER_SOURCE_AC : - SMU_POWER_SOURCE_DC); - if (ret) { - dev_err(adev->dev, "Failed to switch to %s mode!\n", - adev->pm.ac_power ? "AC" : "DC"); - return ret; - } - } return ret; } diff --git a/sys/dev/pci/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/sys/dev/pci/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 92f0de312..2bb5c3872 100644 --- a/sys/dev/pci/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/sys/dev/pci/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -1769,6 +1769,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost, .get_power_limit = smu_v13_0_7_get_power_limit, .set_power_limit = smu_v13_0_set_power_limit, + .set_power_source = smu_v13_0_set_power_source, .get_power_profile_mode = smu_v13_0_7_get_power_profile_mode, .set_power_profile_mode = smu_v13_0_7_set_power_profile_mode, .set_tool_table_location = smu_v13_0_set_tool_table_location, diff --git a/sys/dev/pci/drm/drm_displayid.c b/sys/dev/pci/drm/drm_displayid.c index 38ea8203d..7d03159dc 100644 --- a/sys/dev/pci/drm/drm_displayid.c +++ b/sys/dev/pci/drm/drm_displayid.c @@ -7,13 +7,28 @@ #include #include +static const struct displayid_header * +displayid_get_header(const u8 *displayid, int length, int index) +{ + const struct displayid_header *base; + + if (sizeof(*base) > length - index) + return ERR_PTR(-EINVAL); + + base = (const struct displayid_header *)&displayid[index]; + + return base; +} + static int validate_displayid(const u8 *displayid, int length, int idx) { int i, dispid_length; u8 csum = 0; const struct displayid_header *base; - base = (const struct displayid_header *)&displayid[idx]; + base = displayid_get_header(displayid, length, idx); + if (IS_ERR(base)) + return PTR_ERR(base); DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", base->rev, base->bytes, base->prod_id, base->ext_count); diff --git a/sys/dev/pci/drm/drm_fb_helper.c b/sys/dev/pci/drm/drm_fb_helper.c index b86d690e2..449ee168a 100644 --- a/sys/dev/pci/drm/drm_fb_helper.c +++ b/sys/dev/pci/drm/drm_fb_helper.c @@ -724,19 +724,27 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len, struct drm_rect *clip) { + u32 line_length = info->fix.line_length; + u32 fb_height = info->var.yres; off_t end = off + len; u32 x1 = 0; - u32 y1 = off / info->fix.line_length; + u32 y1 = off / line_length; u32 x2 = info->var.xres; - u32 y2 = DIV_ROUND_UP(end, info->fix.line_length); + u32 y2 = DIV_ROUND_UP(end, line_length); + + /* Don't allow any of them beyond the bottom bound of display area */ + if (y1 > fb_height) + y1 = fb_height; + if (y2 > fb_height) + y2 = fb_height; if ((y2 - y1) == 1) { /* * We've only written to a single scanline. Try to reduce * the number of horizontal pixels that need an update. */ - off_t bit_off = (off % info->fix.line_length) * 8; - off_t bit_end = (end % info->fix.line_length) * 8; + off_t bit_off = (off % line_length) * 8; + off_t bit_end = (end % line_length) * 8; x1 = bit_off / info->var.bits_per_pixel; x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel); diff --git a/sys/dev/pci/drm/drm_mipi_dsi.c b/sys/dev/pci/drm/drm_mipi_dsi.c index a8a0796ae..aacee4326 100644 --- a/sys/dev/pci/drm/drm_mipi_dsi.c +++ b/sys/dev/pci/drm/drm_mipi_dsi.c @@ -223,7 +223,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host, return dsi; } - dsi->dev.of_node = info->node; + device_set_node(&dsi->dev, of_fwnode_handle(info->node)); dsi->channel = info->channel; strlcpy(dsi->name, info->type, sizeof(dsi->name)); diff --git a/sys/dev/pci/drm/i915/display/intel_atomic_plane.c b/sys/dev/pci/drm/i915/display/intel_atomic_plane.c index aaa670825..82826454b 100644 --- a/sys/dev/pci/drm/i915/display/intel_atomic_plane.c +++ b/sys/dev/pci/drm/i915/display/intel_atomic_plane.c @@ -988,7 +988,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, int ret; if (old_obj) { - const struct intel_crtc_state *crtc_state = + const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, to_intel_crtc(old_plane_state->hw.crtc)); @@ -1003,7 +1003,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * This should only fail upon a hung GPU, in which case we * can safely continue. */ - if (intel_crtc_needs_modeset(crtc_state)) { + if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { ret = i915_sw_fence_await_reservation(&state->commit_ready, old_obj->base.resv, NULL, false, 0, diff --git a/sys/dev/pci/drm/i915/display/intel_dp.c b/sys/dev/pci/drm/i915/display/intel_dp.c index dd62aeae5..dd636c23a 100644 --- a/sys/dev/pci/drm/i915/display/intel_dp.c +++ b/sys/dev/pci/drm/i915/display/intel_dp.c @@ -1512,6 +1512,11 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->dsc.slice_count = drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, true); + if (!pipe_config->dsc.slice_count) { + drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n", + pipe_config->dsc.slice_count); + return -EINVAL; + } } else { u16 dsc_max_output_bpp; u8 dsc_dp_slice_count; diff --git a/sys/dev/pci/drm/i915/gt/uc/intel_guc_capture.c b/sys/dev/pci/drm/i915/gt/uc/intel_guc_capture.c index 1e1fa20fb..18a8466f8 100644 --- a/sys/dev/pci/drm/i915/gt/uc/intel_guc_capture.c +++ b/sys/dev/pci/drm/i915/gt/uc/intel_guc_capture.c @@ -30,12 +30,14 @@ { FORCEWAKE_MT, 0, 0, "FORCEWAKE" } #define COMMON_GEN9BASE_GLOBAL \ - { GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \ - { GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" }, \ { ERROR_GEN6, 0, 0, "ERROR_GEN6" }, \ { DONE_REG, 0, 0, "DONE_REG" }, \ { HSW_GTT_CACHE_EN, 0, 0, "HSW_GTT_CACHE_EN" } +#define GEN9_GLOBAL \ + { GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \ + { GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" } + #define COMMON_GEN12BASE_GLOBAL \ { GEN12_FAULT_TLB_DATA0, 0, 0, "GEN12_FAULT_TLB_DATA0" }, \ { GEN12_FAULT_TLB_DATA1, 0, 0, "GEN12_FAULT_TLB_DATA1" }, \ @@ -136,6 +138,7 @@ static const struct __guc_mmio_reg_descr xe_lpd_blt_inst_regs[] = { static const struct __guc_mmio_reg_descr default_global_regs[] = { COMMON_BASE_GLOBAL, COMMON_GEN9BASE_GLOBAL, + GEN9_GLOBAL, }; static const struct __guc_mmio_reg_descr default_rc_class_regs[] = { diff --git a/sys/dev/pci/drm/i915/i915_params.c b/sys/dev/pci/drm/i915/i915_params.c index d1e4d528c..5b24dd50f 100644 --- a/sys/dev/pci/drm/i915/i915_params.c +++ b/sys/dev/pci/drm/i915/i915_params.c @@ -122,7 +122,7 @@ i915_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400, "Default: 0"); i915_param_named_unsafe(force_probe, charp, 0400, - "Force probe the driver for specified devices. " + "Force probe options for specified supported devices. " "See CONFIG_DRM_I915_FORCE_PROBE for details."); i915_param_named_unsafe(disable_power_well, int, 0400, diff --git a/sys/dev/pci/drm/i915/i915_pci.c b/sys/dev/pci/drm/i915/i915_pci.c index 6dedad54a..786903200 100644 --- a/sys/dev/pci/drm/i915/i915_pci.c +++ b/sys/dev/pci/drm/i915/i915_pci.c @@ -1253,7 +1253,7 @@ static void i915_pci_remove(struct pci_dev *pdev) } /* is device_id present in comma separated list of ids */ -static bool force_probe(u16 device_id, const char *devices) +static bool device_id_in_list(u16 device_id, const char *devices, bool negative) { char *s, *p, *tok; bool ret; @@ -1262,7 +1262,9 @@ static bool force_probe(u16 device_id, const char *devices) return false; /* match everything */ - if (strcmp(devices, "*") == 0) + if (negative && strcmp(devices, "!*") == 0) + return true; + if (!negative && strcmp(devices, "*") == 0) return true; s = kstrdup(devices, GFP_KERNEL); @@ -1272,6 +1274,12 @@ static bool force_probe(u16 device_id, const char *devices) for (p = s, ret = false; (tok = strsep(&p, ",")) != NULL; ) { u16 val; + if (negative && tok[0] == '!') + tok++; + else if ((negative && tok[0] != '!') || + (!negative && tok[0] == '!')) + continue; + if (kstrtou16(tok, 16, &val) == 0 && val == device_id) { ret = true; break; @@ -1283,6 +1291,16 @@ static bool force_probe(u16 device_id, const char *devices) return ret; } +static bool id_forced(u16 device_id) +{ + return device_id_in_list(device_id, i915_modparams.force_probe, false); +} + +static bool id_blocked(u16 device_id) +{ + return device_id_in_list(device_id, i915_modparams.force_probe, true); +} + bool i915_pci_resource_valid(struct pci_dev *pdev, int bar) { if (!pci_resource_flags(pdev, bar)) @@ -1310,10 +1328,9 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (struct intel_device_info *) ent->driver_data; int err; - if (intel_info->require_force_probe && - !force_probe(pdev->device, i915_modparams.force_probe)) { + if (intel_info->require_force_probe && !id_forced(pdev->device)) { dev_info(&pdev->dev, - "Your graphics device %04x is not properly supported by the driver in this\n" + "Your graphics device %04x is not properly supported by i915 in this\n" "kernel version. To force driver probe anyway, use i915.force_probe=%04x\n" "module parameter or CONFIG_DRM_I915_FORCE_PROBE=%04x configuration option,\n" "or (recommended) check for kernel updates.\n", @@ -1321,6 +1338,18 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } + if (id_blocked(pdev->device)) { + dev_info(&pdev->dev, "I915 probe blocked for Device ID %04x.\n", + pdev->device); + return -ENODEV; + } + + if (intel_info->require_force_probe) { + dev_info(&pdev->dev, "Force probing unsupported Device ID %04x, tainting kernel\n", + pdev->device); + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + } + /* Only bind to function 0 of the device. Early generations * used function 1 as a placeholder for multi-head. This causes * us confusion instead, especially on the systems where both