sync with OpenBSD -current
This commit is contained in:
parent
4d0363822b
commit
04f8de21b3
56 changed files with 733 additions and 239 deletions
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: GENERIC,v 1.523 2024/05/09 17:05:22 mglocker Exp $
|
||||
# $OpenBSD: GENERIC,v 1.524 2024/08/04 11:05:18 kettenis Exp $
|
||||
#
|
||||
# For further information on compiling SecBSD kernels, see the config(8)
|
||||
# man page.
|
||||
|
@ -88,6 +88,7 @@ acpihid* at acpi?
|
|||
ipmi0 at acpi? disable
|
||||
ccpmic* at iic?
|
||||
tipmic* at iic?
|
||||
intelpmc* at acpi?
|
||||
|
||||
efi0 at bios0
|
||||
mpbios0 at bios0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: specialreg.h,v 1.115 2024/07/21 19:41:31 bluhm Exp $ */
|
||||
/* $OpenBSD: specialreg.h,v 1.116 2024/08/04 11:05:18 kettenis Exp $ */
|
||||
/* $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $ */
|
||||
/* $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $ */
|
||||
|
||||
|
@ -624,6 +624,12 @@
|
|||
#define MSR_PERF_GLOBAL_CTRL 0x38f
|
||||
#define MSR_PERF_GLOBAL_CTR1_EN (1ULL << 33)
|
||||
#define MSR_PERF_GLOBAL_CTR2_EN (1ULL << 34)
|
||||
#define MSR_PKG_C3_RESIDENCY 0x3f8
|
||||
#define MSR_PKG_C6_RESIDENCY 0x3f9
|
||||
#define MSR_PKG_C7_RESIDENCY 0x3fa
|
||||
#define MSR_CORE_C3_RESIDENCY 0x3fc
|
||||
#define MSR_CORE_C6_RESIDENCY 0x3fd
|
||||
#define MSR_CORE_C7_RESIDENCY 0x3fe
|
||||
#define MSR_MC0_CTL 0x400
|
||||
#define MSR_MC0_STATUS 0x401
|
||||
#define MSR_MC0_ADDR 0x402
|
||||
|
@ -644,6 +650,10 @@
|
|||
#define MSR_MC3_STATUS 0x411
|
||||
#define MSR_MC3_ADDR 0x412
|
||||
#define MSR_MC3_MISC 0x413
|
||||
#define MSR_PKG_C2_RESIDENCY 0x60d
|
||||
#define MSR_PKG_C8_RESIDENCY 0x630
|
||||
#define MSR_PKG_C9_RESIDENCY 0x631
|
||||
#define MSR_PKG_C10_RESIDENCY 0x632
|
||||
#define MSR_U_CET 0x6a0
|
||||
#define MSR_CET_ENDBR_EN (1 << 2)
|
||||
#define MSR_CET_NO_TRACK_EN (1 << 4)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: intr.c,v 1.28 2024/05/26 13:37:31 kettenis Exp $ */
|
||||
/* $OpenBSD: intr.c,v 1.29 2024/08/04 12:01:18 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
|
||||
*
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
uint32_t arm_intr_get_parent(int);
|
||||
int arm_intr_get_parent(int);
|
||||
uint32_t arm_intr_map_msi(int, uint64_t *);
|
||||
|
||||
void *arm_intr_prereg_establish_fdt(void *, int *, int, struct cpu_info *,
|
||||
|
@ -94,17 +94,21 @@ arm_cpu_fiq(void *frame)
|
|||
/*
|
||||
* Find the interrupt parent by walking up the tree.
|
||||
*/
|
||||
uint32_t
|
||||
int
|
||||
arm_intr_get_parent(int node)
|
||||
{
|
||||
uint32_t phandle = 0;
|
||||
uint32_t phandle;
|
||||
|
||||
while (node && !phandle) {
|
||||
while (node) {
|
||||
phandle = OF_getpropint(node, "interrupt-parent", 0);
|
||||
if (phandle)
|
||||
return OF_getnodebyphandle(phandle);
|
||||
node = OF_parent(node);
|
||||
if (OF_getpropbool(node, "interrupt-controller"))
|
||||
return node;
|
||||
}
|
||||
|
||||
return phandle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -291,8 +295,6 @@ arm_intr_register_fdt(struct interrupt_controller *ic)
|
|||
|
||||
ic->ic_cells = OF_getpropint(ic->ic_node, "#interrupt-cells", 0);
|
||||
ic->ic_phandle = OF_getpropint(ic->ic_node, "phandle", 0);
|
||||
if (ic->ic_phandle == 0)
|
||||
return;
|
||||
KASSERT(ic->ic_cells <= MAX_INTERRUPT_CELLS);
|
||||
|
||||
LIST_INSERT_HEAD(&interrupt_controllers, ic, ic_list);
|
||||
|
@ -341,7 +343,8 @@ arm_intr_establish_fdt_idx_cpu(int node, int idx, int level, struct cpu_info *ci
|
|||
int (*func)(void *), void *cookie, char *name)
|
||||
{
|
||||
struct interrupt_controller *ic;
|
||||
int i, len, ncells, extended = 1;
|
||||
int i, len, ncells, parent;
|
||||
int extended = 1;
|
||||
uint32_t *cell, *cells, phandle;
|
||||
struct machine_intr_handle *ih;
|
||||
void *val = NULL;
|
||||
|
@ -356,9 +359,9 @@ arm_intr_establish_fdt_idx_cpu(int node, int idx, int level, struct cpu_info *ci
|
|||
|
||||
/* Old style. */
|
||||
if (!extended) {
|
||||
phandle = arm_intr_get_parent(node);
|
||||
parent = arm_intr_get_parent(node);
|
||||
LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
|
||||
if (ic->ic_phandle == phandle)
|
||||
if (ic->ic_node == parent)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -569,12 +572,12 @@ arm_intr_parent_establish_fdt(void *cookie, int *cell, int level,
|
|||
{
|
||||
struct interrupt_controller *ic = cookie;
|
||||
struct machine_intr_handle *ih;
|
||||
uint32_t phandle;
|
||||
int parent;
|
||||
void *val;
|
||||
|
||||
phandle = arm_intr_get_parent(ic->ic_node);
|
||||
parent = arm_intr_get_parent(ic->ic_node);
|
||||
LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
|
||||
if (ic->ic_phandle == phandle)
|
||||
if (ic->ic_node == parent)
|
||||
break;
|
||||
}
|
||||
if (ic == NULL)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: acpi_x86.c,v 1.22 2024/06/25 11:57:10 kettenis Exp $ */
|
||||
/* $OpenBSD: acpi_x86.c,v 1.23 2024/08/04 11:05:18 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
|
||||
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
|
||||
|
@ -104,9 +104,15 @@ gosleep(void *v)
|
|||
acpi_disable_allgpes(sc);
|
||||
acpi_enable_wakegpes(sc, sc->sc_state);
|
||||
|
||||
if (sc->sc_pmc_suspend)
|
||||
sc->sc_pmc_suspend(sc->sc_pmc_cookie);
|
||||
|
||||
ret = acpi_sleep_cpu(sc, sc->sc_state);
|
||||
acpi_resume_cpu(sc, sc->sc_state);
|
||||
|
||||
if (sc->sc_pmc_resume)
|
||||
sc->sc_pmc_resume(sc->sc_pmc_cookie);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: acpivar.h,v 1.131 2024/06/30 00:29:36 jsg Exp $ */
|
||||
/* $OpenBSD: acpivar.h,v 1.132 2024/08/04 11:05:18 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
|
||||
*
|
||||
|
@ -282,6 +282,10 @@ struct acpi_softc {
|
|||
int sc_flags;
|
||||
|
||||
int sc_skip_processor;
|
||||
|
||||
void (*sc_pmc_suspend)(void *);
|
||||
void (*sc_pmc_resume)(void *);
|
||||
void *sc_pmc_cookie;
|
||||
};
|
||||
|
||||
extern struct acpi_softc *acpi_softc;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: files.acpi,v 1.70 2024/07/30 19:47:06 mglocker Exp $
|
||||
# $OpenBSD: files.acpi,v 1.71 2024/08/04 11:05:18 kettenis Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent ACPI code.
|
||||
# Included by ports that need it.
|
||||
|
@ -284,3 +284,8 @@ file dev/acpi/ufshci_acpi.c ufshci_acpi
|
|||
# Intel OnChip System Fabric
|
||||
attach iosf at acpi with iosf_acpi
|
||||
file dev/acpi/iosf_acpi.c iosf_acpi
|
||||
|
||||
# Intel Power Management Controller
|
||||
device intelpmc
|
||||
attach intelpmc at acpi
|
||||
file dev/acpi/intelpmc.c intelpmc
|
||||
|
|
220
sys/dev/acpi/intelpmc.c
Normal file
220
sys/dev/acpi/intelpmc.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
/* $OpenBSD: intelpmc.c,v 1.1 2024/08/04 11:05:18 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2024 Mark Kettenis <kettenis@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/intr.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/acpi/acpireg.h>
|
||||
#include <dev/acpi/acpivar.h>
|
||||
#include <dev/acpi/acpidev.h>
|
||||
#include <dev/acpi/amltypes.h>
|
||||
#include <dev/acpi/dsdt.h>
|
||||
|
||||
#define INTELPMC_DEBUG
|
||||
|
||||
/* Low Power S0 Idle DSM methods */
|
||||
#define ACPI_LPS0_ENUM_FUNCTIONS 0
|
||||
#define ACPI_LPS0_GET_CONSTRAINTS 1
|
||||
#define ACPI_LPS0_SCREEN_OFF 3
|
||||
#define ACPI_LPS0_SCREEN_ON 4
|
||||
#define ACPI_LPS0_ENTRY 5
|
||||
#define ACPI_LPS0_EXIT 6
|
||||
|
||||
struct intelpmc_softc {
|
||||
struct device sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
|
||||
struct acpi_softc *sc_acpi;
|
||||
struct aml_node *sc_node;
|
||||
|
||||
#ifdef INTELPMC_DEBUG
|
||||
uint64_t sc_c3[2];
|
||||
uint64_t sc_c6[2];
|
||||
uint64_t sc_c7[2];
|
||||
uint64_t sc_pc2[2];
|
||||
uint64_t sc_pc3[2];
|
||||
uint64_t sc_pc6[2];
|
||||
uint64_t sc_pc7[2];
|
||||
uint64_t sc_pc8[2];
|
||||
uint64_t sc_pc9[2];
|
||||
uint64_t sc_pc10[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
int intelpmc_match(struct device *, void *, void *);
|
||||
void intelpmc_attach(struct device *, struct device *, void *);
|
||||
int intelpmc_activate(struct device *, int);
|
||||
|
||||
const struct cfattach intelpmc_ca = {
|
||||
sizeof (struct intelpmc_softc), intelpmc_match, intelpmc_attach,
|
||||
NULL, intelpmc_activate
|
||||
};
|
||||
|
||||
struct cfdriver intelpmc_cd = {
|
||||
NULL, "intelpmc", DV_DULL
|
||||
};
|
||||
|
||||
const char *intelpmc_hids[] = {
|
||||
"INT33A1",
|
||||
NULL
|
||||
};
|
||||
|
||||
void intelpmc_suspend(void *);
|
||||
void intelpmc_resume(void *);
|
||||
|
||||
int
|
||||
intelpmc_match(struct device *parent, void *match, void *aux)
|
||||
{
|
||||
struct acpi_attach_args *aaa = aux;
|
||||
struct cfdata *cf = match;
|
||||
|
||||
return acpi_matchhids(aaa, intelpmc_hids, cf->cf_driver->cd_name);
|
||||
}
|
||||
|
||||
void
|
||||
intelpmc_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct intelpmc_softc *sc = (struct intelpmc_softc *)self;
|
||||
struct acpi_attach_args *aaa = aux;
|
||||
|
||||
sc->sc_acpi = (struct acpi_softc *)parent;
|
||||
sc->sc_node = aaa->aaa_node;
|
||||
|
||||
printf(": %s\n", aaa->aaa_node->name);
|
||||
|
||||
sc->sc_acpi->sc_pmc_suspend = intelpmc_suspend;
|
||||
sc->sc_acpi->sc_pmc_resume = intelpmc_resume;
|
||||
sc->sc_acpi->sc_pmc_cookie = sc;
|
||||
}
|
||||
|
||||
int
|
||||
intelpmc_activate(struct device *self, int act)
|
||||
{
|
||||
#ifdef INTELPMC_DEBUG
|
||||
struct intelpmc_softc *sc = (struct intelpmc_softc *)self;
|
||||
|
||||
switch (act) {
|
||||
case DVACT_RESUME:
|
||||
printf("C3: %lld -> %lld\n", sc->sc_c3[0], sc->sc_c3[1]);
|
||||
printf("C6: %lld -> %lld\n", sc->sc_c6[0], sc->sc_c6[1]);
|
||||
printf("C7: %lld -> %lld\n", sc->sc_c7[0], sc->sc_c7[1]);
|
||||
printf("PC2: %lld -> %lld\n", sc->sc_pc2[0], sc->sc_pc2[1]);
|
||||
printf("PC3: %lld -> %lld\n", sc->sc_pc3[0], sc->sc_pc3[1]);
|
||||
printf("PC6: %lld -> %lld\n", sc->sc_pc6[0], sc->sc_pc6[1]);
|
||||
printf("PC7: %lld -> %lld\n", sc->sc_pc7[0], sc->sc_pc7[1]);
|
||||
printf("PC8: %lld -> %lld\n", sc->sc_pc8[0], sc->sc_pc8[1]);
|
||||
printf("PC9: %lld -> %lld\n", sc->sc_pc9[0], sc->sc_pc9[1]);
|
||||
printf("PC10: %lld -> %lld\n", sc->sc_pc10[0], sc->sc_pc10[1]);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intelpmc_dsm(struct acpi_softc *sc, struct aml_node *node, int func)
|
||||
{
|
||||
struct aml_value cmd[4];
|
||||
struct aml_value res;
|
||||
|
||||
/* c4eb40a0-6cd2-11e2-bcfd-0800200c9a66 */
|
||||
static uint8_t lps0_dsm_guid[] = {
|
||||
0xA0, 0x40, 0xEB, 0xC4, 0xD2, 0x6C, 0xE2, 0x11,
|
||||
0xBC, 0xFD, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66,
|
||||
};
|
||||
|
||||
bzero(&cmd, sizeof(cmd));
|
||||
cmd[0].type = AML_OBJTYPE_BUFFER;
|
||||
cmd[0].v_buffer = (uint8_t *)&lps0_dsm_guid;
|
||||
cmd[0].length = sizeof(lps0_dsm_guid);
|
||||
/* rev */
|
||||
cmd[1].type = AML_OBJTYPE_INTEGER;
|
||||
cmd[1].v_integer = 0;
|
||||
cmd[1].length = 1;
|
||||
/* func */
|
||||
cmd[2].type = AML_OBJTYPE_INTEGER;
|
||||
cmd[2].v_integer = func;
|
||||
cmd[2].length = 1;
|
||||
/* not used */
|
||||
cmd[3].type = AML_OBJTYPE_PACKAGE;
|
||||
cmd[3].length = 0;
|
||||
|
||||
if (aml_evalname(sc, node, "_DSM", 4, cmd, &res)) {
|
||||
printf("%s: eval of _DSM at %s failed\n",
|
||||
sc->sc_dev.dv_xname, aml_nodename(node));
|
||||
return 1;
|
||||
}
|
||||
aml_freevalue(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
intelpmc_suspend(void *cookie)
|
||||
{
|
||||
struct intelpmc_softc *sc = cookie;
|
||||
|
||||
if (sc->sc_acpi->sc_state != ACPI_STATE_S0)
|
||||
return;
|
||||
|
||||
#ifdef INTELPMC_DEBUG
|
||||
rdmsr_safe(MSR_CORE_C3_RESIDENCY, &sc->sc_c3[0]);
|
||||
rdmsr_safe(MSR_CORE_C6_RESIDENCY, &sc->sc_c6[0]);
|
||||
rdmsr_safe(MSR_CORE_C7_RESIDENCY, &sc->sc_c7[0]);
|
||||
rdmsr_safe(MSR_PKG_C2_RESIDENCY, &sc->sc_pc2[0]);
|
||||
rdmsr_safe(MSR_PKG_C3_RESIDENCY, &sc->sc_pc3[0]);
|
||||
rdmsr_safe(MSR_PKG_C6_RESIDENCY, &sc->sc_pc6[0]);
|
||||
rdmsr_safe(MSR_PKG_C7_RESIDENCY, &sc->sc_pc7[0]);
|
||||
rdmsr_safe(MSR_PKG_C8_RESIDENCY, &sc->sc_pc8[0]);
|
||||
rdmsr_safe(MSR_PKG_C9_RESIDENCY, &sc->sc_pc9[0]);
|
||||
rdmsr_safe(MSR_PKG_C10_RESIDENCY, &sc->sc_pc10[0]);
|
||||
#endif
|
||||
|
||||
intelpmc_dsm(sc->sc_acpi, sc->sc_node, ACPI_LPS0_SCREEN_OFF);
|
||||
intelpmc_dsm(sc->sc_acpi, sc->sc_node, ACPI_LPS0_ENTRY);
|
||||
}
|
||||
|
||||
void
|
||||
intelpmc_resume(void *cookie)
|
||||
{
|
||||
struct intelpmc_softc *sc = cookie;
|
||||
|
||||
if (sc->sc_acpi->sc_state != ACPI_STATE_S0)
|
||||
return;
|
||||
|
||||
intelpmc_dsm(sc->sc_acpi, sc->sc_node, ACPI_LPS0_EXIT);
|
||||
intelpmc_dsm(sc->sc_acpi, sc->sc_node, ACPI_LPS0_SCREEN_ON);
|
||||
|
||||
#ifdef INTELPMC_DEBUG
|
||||
rdmsr_safe(MSR_CORE_C3_RESIDENCY, &sc->sc_c3[1]);
|
||||
rdmsr_safe(MSR_CORE_C6_RESIDENCY, &sc->sc_c6[1]);
|
||||
rdmsr_safe(MSR_CORE_C7_RESIDENCY, &sc->sc_c7[1]);
|
||||
rdmsr_safe(MSR_PKG_C2_RESIDENCY, &sc->sc_pc2[1]);
|
||||
rdmsr_safe(MSR_PKG_C3_RESIDENCY, &sc->sc_pc3[1]);
|
||||
rdmsr_safe(MSR_PKG_C6_RESIDENCY, &sc->sc_pc6[1]);
|
||||
rdmsr_safe(MSR_PKG_C7_RESIDENCY, &sc->sc_pc7[1]);
|
||||
rdmsr_safe(MSR_PKG_C8_RESIDENCY, &sc->sc_pc8[1]);
|
||||
rdmsr_safe(MSR_PKG_C9_RESIDENCY, &sc->sc_pc9[1]);
|
||||
rdmsr_safe(MSR_PKG_C10_RESIDENCY, &sc->sc_pc10[1]);
|
||||
#endif
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: qcpas.c,v 1.3 2024/07/25 20:21:40 kettenis Exp $ */
|
||||
/* $OpenBSD: qcpas.c,v 1.5 2024/08/04 20:10:38 mglocker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2023 Patrick Wildt <patrick@blueri.se>
|
||||
*
|
||||
|
@ -36,6 +36,11 @@
|
|||
|
||||
#include "apm.h"
|
||||
|
||||
extern int qcscm_pas_init_image(uint32_t, paddr_t);
|
||||
extern int qcscm_pas_mem_setup(uint32_t, paddr_t, size_t);
|
||||
extern int qcscm_pas_auth_and_reset(uint32_t);
|
||||
extern int qcscm_pas_shutdown(uint32_t);
|
||||
|
||||
#define MDT_TYPE_MASK (7 << 24)
|
||||
#define MDT_TYPE_HASH (2 << 24)
|
||||
#define MDT_RELOCATABLE (1 << 27)
|
||||
|
@ -65,15 +70,17 @@ struct qcpas_softc {
|
|||
|
||||
void *sc_ih[6];
|
||||
|
||||
paddr_t sc_mem_phys;
|
||||
size_t sc_mem_size;
|
||||
void *sc_mem_region;
|
||||
vaddr_t sc_mem_reloc;
|
||||
paddr_t sc_mem_phys[2];
|
||||
size_t sc_mem_size[2];
|
||||
void *sc_mem_region[2];
|
||||
vaddr_t sc_mem_reloc[2];
|
||||
|
||||
uint32_t sc_pas_id;
|
||||
uint32_t sc_dtb_pas_id;
|
||||
uint32_t sc_lite_pas_id;
|
||||
char *sc_load_state;
|
||||
|
||||
struct qcpas_dmamem *sc_metadata;
|
||||
struct qcpas_dmamem *sc_metadata[2];
|
||||
|
||||
/* GLINK */
|
||||
volatile uint32_t *sc_tx_tail;
|
||||
|
@ -110,7 +117,7 @@ struct cfdriver qcpas_cd = {
|
|||
|
||||
void qcpas_mountroot(struct device *);
|
||||
int qcpas_map_memory(struct qcpas_softc *);
|
||||
int qcpas_mdt_init(struct qcpas_softc *, u_char *, size_t);
|
||||
int qcpas_mdt_init(struct qcpas_softc *, int, u_char *, size_t);
|
||||
void qcpas_glink_attach(struct qcpas_softc *, int);
|
||||
|
||||
struct qcpas_dmamem *
|
||||
|
@ -130,7 +137,8 @@ qcpas_match(struct device *parent, void *match, void *aux)
|
|||
{
|
||||
struct fdt_attach_args *faa = aux;
|
||||
|
||||
return OF_is_compatible(faa->fa_node, "qcom,sc8280xp-adsp-pas");
|
||||
return OF_is_compatible(faa->fa_node, "qcom,sc8280xp-adsp-pas") ||
|
||||
OF_is_compatible(faa->fa_node, "qcom,x1e80100-adsp-pas");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -164,6 +172,13 @@ qcpas_attach(struct device *parent, struct device *self, void *aux)
|
|||
sc->sc_pas_id = 30;
|
||||
}
|
||||
|
||||
if (OF_is_compatible(faa->fa_node, "qcom,x1e80100-adsp-pas")) {
|
||||
sc->sc_pas_id = 1;
|
||||
sc->sc_dtb_pas_id = 36;
|
||||
sc->sc_lite_pas_id = 31;
|
||||
sc->sc_load_state = "adsp";
|
||||
}
|
||||
|
||||
qcpas_intr_establish(sc, 0, "wdog", qcpas_intr_wdog);
|
||||
qcpas_intr_establish(sc, 1, "fatal", qcpas_intr_fatal);
|
||||
qcpas_intr_establish(sc, 2, "ready", qcpas_intr_ready);
|
||||
|
@ -182,10 +197,11 @@ void
|
|||
qcpas_mountroot(struct device *self)
|
||||
{
|
||||
struct qcpas_softc *sc = (struct qcpas_softc *)self;
|
||||
char fwname[64];
|
||||
size_t fwlen;
|
||||
u_char *fw;
|
||||
char fwname[128];
|
||||
size_t fwlen, dtb_fwlen;
|
||||
u_char *fw, *dtb_fw;
|
||||
int node, ret;
|
||||
int error;
|
||||
|
||||
if (qcpas_map_memory(sc) != 0)
|
||||
return;
|
||||
|
@ -195,10 +211,32 @@ qcpas_mountroot(struct device *self)
|
|||
OF_getprop(sc->sc_node, "firmware-name", fwname, sizeof(fwname));
|
||||
fwname[sizeof(fwname) - 1] = '\0';
|
||||
|
||||
if (loadfirmware(fwname, &fw, &fwlen) != 0) {
|
||||
printf("%s: failed to load %s\n",
|
||||
sc->sc_dev.dv_xname, fwname);
|
||||
/* If we need a second firmware, make sure we have a name for it. */
|
||||
if (sc->sc_dtb_pas_id && strlen(fwname) == sizeof(fwname) - 1)
|
||||
return;
|
||||
|
||||
error = loadfirmware(fwname, &fw, &fwlen);
|
||||
if (error) {
|
||||
printf("%s: failed to load %s: %d\n",
|
||||
sc->sc_dev.dv_xname, fwname, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc->sc_lite_pas_id) {
|
||||
if (qcscm_pas_shutdown(sc->sc_lite_pas_id)) {
|
||||
printf("%s: failed to shutdown lite firmware\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_dtb_pas_id) {
|
||||
error = loadfirmware(fwname + strlen(fwname) + 1,
|
||||
&dtb_fw, &dtb_fwlen);
|
||||
if (error) {
|
||||
printf("%s: failed to load %s: %d\n",
|
||||
sc->sc_dev.dv_xname, fwname, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_load_state) {
|
||||
|
@ -217,7 +255,12 @@ qcpas_mountroot(struct device *self)
|
|||
power_domain_enable_all(sc->sc_node);
|
||||
clock_enable(sc->sc_node, "xo");
|
||||
|
||||
ret = qcpas_mdt_init(sc, fw, fwlen);
|
||||
if (sc->sc_dtb_pas_id) {
|
||||
qcpas_mdt_init(sc, sc->sc_dtb_pas_id, dtb_fw, dtb_fwlen);
|
||||
free(dtb_fw, M_DEVBUF, dtb_fwlen);
|
||||
}
|
||||
|
||||
ret = qcpas_mdt_init(sc, sc->sc_pas_id, fw, fwlen);
|
||||
free(fw, M_DEVBUF, fwlen);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed to boot coprocessor\n",
|
||||
|
@ -233,44 +276,49 @@ qcpas_mountroot(struct device *self)
|
|||
int
|
||||
qcpas_map_memory(struct qcpas_softc *sc)
|
||||
{
|
||||
uint32_t phandle, reg[4];
|
||||
uint32_t memreg[2] = {};
|
||||
uint32_t reg[4];
|
||||
size_t off;
|
||||
int node;
|
||||
int i;
|
||||
|
||||
phandle = OF_getpropint(sc->sc_node, "memory-region", 0);
|
||||
if (phandle == 0)
|
||||
return EINVAL;
|
||||
node = OF_getnodebyphandle(phandle);
|
||||
if (node == 0)
|
||||
return EINVAL;
|
||||
if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg))
|
||||
OF_getpropintarray(sc->sc_node, "memory-region",
|
||||
memreg, sizeof(memreg));
|
||||
if (memreg[0] == 0)
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_mem_phys = (uint64_t)reg[0] << 32 | reg[1];
|
||||
KASSERT((sc->sc_mem_phys & PAGE_MASK) == 0);
|
||||
sc->sc_mem_size = (uint64_t)reg[2] << 32 | reg[3];
|
||||
KASSERT((sc->sc_mem_size & PAGE_MASK) == 0);
|
||||
for (i = 0; i < nitems(memreg); i++) {
|
||||
if (memreg[i] == 0)
|
||||
break;
|
||||
node = OF_getnodebyphandle(memreg[i]);
|
||||
if (node == 0)
|
||||
return EINVAL;
|
||||
if (OF_getpropintarray(node, "reg", reg,
|
||||
sizeof(reg)) != sizeof(reg))
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_mem_region = km_alloc(sc->sc_mem_size, &kv_any, &kp_none,
|
||||
&kd_nowait);
|
||||
if (!sc->sc_mem_region)
|
||||
return ENOMEM;
|
||||
sc->sc_mem_phys[i] = (uint64_t)reg[0] << 32 | reg[1];
|
||||
KASSERT((sc->sc_mem_phys[i] & PAGE_MASK) == 0);
|
||||
sc->sc_mem_size[i] = (uint64_t)reg[2] << 32 | reg[3];
|
||||
KASSERT((sc->sc_mem_size[i] & PAGE_MASK) == 0);
|
||||
|
||||
for (off = 0; off < sc->sc_mem_size; off += PAGE_SIZE) {
|
||||
pmap_kenter_cache((vaddr_t)sc->sc_mem_region + off,
|
||||
sc->sc_mem_phys + off, PROT_READ | PROT_WRITE,
|
||||
PMAP_CACHE_DEV_NGNRNE);
|
||||
sc->sc_mem_region[i] = km_alloc(sc->sc_mem_size[i],
|
||||
&kv_any, &kp_none, &kd_nowait);
|
||||
if (!sc->sc_mem_region[i])
|
||||
return ENOMEM;
|
||||
|
||||
for (off = 0; off < sc->sc_mem_size[i]; off += PAGE_SIZE) {
|
||||
pmap_kenter_cache((vaddr_t)sc->sc_mem_region[i] + off,
|
||||
sc->sc_mem_phys[i] + off, PROT_READ | PROT_WRITE,
|
||||
PMAP_CACHE_DEV_NGNRNE);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int qcscm_pas_init_image(uint32_t, paddr_t);
|
||||
extern int qcscm_pas_mem_setup(uint32_t, paddr_t, size_t);
|
||||
extern int qcscm_pas_auth_and_reset(uint32_t);
|
||||
|
||||
int
|
||||
qcpas_mdt_init(struct qcpas_softc *sc, u_char *fw, size_t fwlen)
|
||||
qcpas_mdt_init(struct qcpas_softc *sc, int pas_id, u_char *fw, size_t fwlen)
|
||||
{
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
|
@ -278,6 +326,12 @@ qcpas_mdt_init(struct qcpas_softc *sc, u_char *fw, size_t fwlen)
|
|||
int i, hashseg = 0, relocate = 0;
|
||||
int error;
|
||||
ssize_t off;
|
||||
int idx;
|
||||
|
||||
if (pas_id == sc->sc_dtb_pas_id)
|
||||
idx = 1;
|
||||
else
|
||||
idx = 0;
|
||||
|
||||
ehdr = (Elf32_Ehdr *)fw;
|
||||
phdr = (Elf32_Phdr *)&ehdr[1];
|
||||
|
@ -306,17 +360,17 @@ qcpas_mdt_init(struct qcpas_softc *sc, u_char *fw, size_t fwlen)
|
|||
if (!hashseg)
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_metadata = qcpas_dmamem_alloc(sc, phdr[0].p_filesz +
|
||||
sc->sc_metadata[idx] = qcpas_dmamem_alloc(sc, phdr[0].p_filesz +
|
||||
phdr[hashseg].p_filesz, PAGE_SIZE);
|
||||
if (sc->sc_metadata == NULL)
|
||||
if (sc->sc_metadata[idx] == NULL)
|
||||
return EINVAL;
|
||||
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata), fw, phdr[0].p_filesz);
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata[idx]), fw, phdr[0].p_filesz);
|
||||
if (phdr[0].p_filesz + phdr[hashseg].p_filesz == fwlen) {
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata) + phdr[0].p_filesz,
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata[idx]) + phdr[0].p_filesz,
|
||||
fw + phdr[0].p_filesz, phdr[hashseg].p_filesz);
|
||||
} else if (phdr[hashseg].p_offset + phdr[hashseg].p_filesz <= fwlen) {
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata) + phdr[0].p_filesz,
|
||||
memcpy(QCPAS_DMA_KVA(sc->sc_metadata[idx]) + phdr[0].p_filesz,
|
||||
fw + phdr[hashseg].p_offset, phdr[hashseg].p_filesz);
|
||||
} else {
|
||||
printf("%s: metadata split segment not supported\n",
|
||||
|
@ -326,36 +380,36 @@ qcpas_mdt_init(struct qcpas_softc *sc, u_char *fw, size_t fwlen)
|
|||
|
||||
membar_producer();
|
||||
|
||||
if (qcscm_pas_init_image(sc->sc_pas_id,
|
||||
QCPAS_DMA_DVA(sc->sc_metadata)) != 0) {
|
||||
if (qcscm_pas_init_image(pas_id,
|
||||
QCPAS_DMA_DVA(sc->sc_metadata[idx])) != 0) {
|
||||
printf("%s: init image failed\n", sc->sc_dev.dv_xname);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata[idx]);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (qcscm_pas_mem_setup(sc->sc_pas_id,
|
||||
sc->sc_mem_phys, maxpa - minpa) != 0) {
|
||||
if (qcscm_pas_mem_setup(pas_id,
|
||||
sc->sc_mem_phys[idx], maxpa - minpa) != 0) {
|
||||
printf("%s: mem setup failed\n", sc->sc_dev.dv_xname);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata[idx]);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
sc->sc_mem_reloc = relocate ? minpa : sc->sc_mem_phys;
|
||||
sc->sc_mem_reloc[idx] = relocate ? minpa : sc->sc_mem_phys[idx];
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||
if ((phdr[i].p_flags & MDT_TYPE_MASK) == MDT_TYPE_HASH ||
|
||||
phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0)
|
||||
continue;
|
||||
off = phdr[i].p_paddr - sc->sc_mem_reloc;
|
||||
if (off < 0 || off + phdr[i].p_memsz > sc->sc_mem_size)
|
||||
off = phdr[i].p_paddr - sc->sc_mem_reloc[idx];
|
||||
if (off < 0 || off + phdr[i].p_memsz > sc->sc_mem_size[0])
|
||||
return EINVAL;
|
||||
if (phdr[i].p_filesz > phdr[i].p_memsz)
|
||||
return EINVAL;
|
||||
|
||||
if (phdr[i].p_filesz && phdr[i].p_offset < fwlen &&
|
||||
phdr[i].p_offset + phdr[i].p_filesz <= fwlen) {
|
||||
memcpy(sc->sc_mem_region + off, fw + phdr[i].p_offset,
|
||||
phdr[i].p_filesz);
|
||||
memcpy(sc->sc_mem_region[idx] + off,
|
||||
fw + phdr[i].p_offset, phdr[i].p_filesz);
|
||||
} else if (phdr[i].p_filesz) {
|
||||
printf("%s: firmware split segment not supported\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
|
@ -363,18 +417,21 @@ qcpas_mdt_init(struct qcpas_softc *sc, u_char *fw, size_t fwlen)
|
|||
}
|
||||
|
||||
if (phdr[i].p_memsz > phdr[i].p_filesz)
|
||||
memset(sc->sc_mem_region + off + phdr[i].p_filesz, 0,
|
||||
phdr[i].p_memsz - phdr[i].p_filesz);
|
||||
memset(sc->sc_mem_region[idx] + off + phdr[i].p_filesz,
|
||||
0, phdr[i].p_memsz - phdr[i].p_filesz);
|
||||
}
|
||||
|
||||
membar_producer();
|
||||
|
||||
if (qcscm_pas_auth_and_reset(sc->sc_pas_id) != 0) {
|
||||
if (qcscm_pas_auth_and_reset(pas_id) != 0) {
|
||||
printf("%s: auth and reset failed\n", sc->sc_dev.dv_xname);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata);
|
||||
qcpas_dmamem_free(sc, sc->sc_metadata[idx]);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (pas_id == sc->sc_dtb_pas_id)
|
||||
return 0;
|
||||
|
||||
error = tsleep_nsec(sc, PWAIT, "qcpas", SEC_TO_NSEC(5));
|
||||
if (error) {
|
||||
printf("%s: failed to receive ready signal\n",
|
||||
|
@ -1219,7 +1276,7 @@ qcpas_pmic_rtr_recv(void *cookie, uint8_t *buf, int len)
|
|||
break;
|
||||
case BATTMGR_OPCODE_BAT_INFO: {
|
||||
struct battmgr_bat_info *bat;
|
||||
if (len - sizeof(hdr) != sizeof(*bat)) {
|
||||
if (len - sizeof(hdr) < sizeof(*bat)) {
|
||||
printf("%s: invalid battgmr bat info\n",
|
||||
__func__);
|
||||
return 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: qcscm.c,v 1.8 2024/07/10 10:53:55 kettenis Exp $ */
|
||||
/* $OpenBSD: qcscm.c,v 1.9 2024/08/04 15:30:08 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
|
||||
*
|
||||
|
@ -922,6 +922,33 @@ qcscm_pas_auth_and_reset(uint32_t peripheral)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
qcscm_pas_shutdown(uint32_t peripheral)
|
||||
{
|
||||
struct qcscm_softc *sc = qcscm_sc;
|
||||
uint64_t res[3];
|
||||
uint64_t args[1];
|
||||
uint32_t arginfo;
|
||||
int ret;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
arginfo = QCSCM_ARGINFO_NUM(nitems(args));
|
||||
arginfo |= QCSCM_ARGINFO_TYPE(0, QCSCM_ARGINFO_TYPE_VAL);
|
||||
args[0] = peripheral;
|
||||
|
||||
/* Make call into TEE */
|
||||
ret = qcscm_smc_call(sc, ARM_SMCCC_OWNER_SIP, QCSCM_SVC_PIL,
|
||||
QCSCM_PIL_PAS_SHUTDOWN, arginfo, args, nitems(args), res);
|
||||
|
||||
/* If the call succeeded, check the response status */
|
||||
if (ret == 0)
|
||||
ret = res[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* DMA code */
|
||||
struct qcscm_dmamem *
|
||||
qcscm_dmamem_alloc(struct qcscm_softc *sc, bus_size_t size, bus_size_t align)
|
||||
|
|
|
@ -5775,7 +5775,7 @@ int amdgpu_device_baco_exit(struct drm_device *dev)
|
|||
adev->nbio.funcs->enable_doorbell_interrupt)
|
||||
adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
|
||||
|
||||
if (amdgpu_passthrough(adev) &&
|
||||
if (amdgpu_passthrough(adev) && adev->nbio.funcs &&
|
||||
adev->nbio.funcs->clear_doorbell_interrupt)
|
||||
adev->nbio.funcs->clear_doorbell_interrupt(adev);
|
||||
|
||||
|
|
|
@ -650,7 +650,6 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
|||
struct amdgpu_gmc *gmc = &adev->gmc;
|
||||
uint32_t gc_ver = adev->ip_versions[GC_HWIP][0];
|
||||
bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) ||
|
||||
gc_ver == IP_VERSION(9, 3, 0) ||
|
||||
gc_ver == IP_VERSION(9, 4, 0) ||
|
||||
gc_ver == IP_VERSION(9, 4, 1) ||
|
||||
gc_ver == IP_VERSION(9, 4, 2) ||
|
||||
|
|
|
@ -478,7 +478,7 @@ uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
if (!vm)
|
||||
return result;
|
||||
|
||||
result += vm->generation;
|
||||
result += lower_32_bits(vm->generation);
|
||||
/* Add one if the page tables will be re-generated on next CS */
|
||||
if (drm_sched_entity_error(&vm->delayed))
|
||||
++result;
|
||||
|
@ -503,13 +503,14 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
int (*validate)(void *p, struct amdgpu_bo *bo),
|
||||
void *param)
|
||||
{
|
||||
uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm);
|
||||
struct amdgpu_vm_bo_base *bo_base;
|
||||
struct amdgpu_bo *shadow;
|
||||
struct amdgpu_bo *bo;
|
||||
int r;
|
||||
|
||||
if (drm_sched_entity_error(&vm->delayed)) {
|
||||
++vm->generation;
|
||||
if (vm->generation != new_vm_generation) {
|
||||
vm->generation = new_vm_generation;
|
||||
amdgpu_vm_bo_reset_state_machine(vm);
|
||||
amdgpu_vm_fini_entities(vm);
|
||||
r = amdgpu_vm_init_entities(adev, vm);
|
||||
|
@ -2265,7 +2266,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
vm->last_update = dma_fence_get_stub();
|
||||
vm->last_unlocked = dma_fence_get_stub();
|
||||
vm->last_tlb_flush = dma_fence_get_stub();
|
||||
vm->generation = 0;
|
||||
vm->generation = amdgpu_vm_generation(adev, NULL);
|
||||
|
||||
rw_init(&vm->eviction_lock, "avmev");
|
||||
vm->evicting = false;
|
||||
|
|
|
@ -1956,7 +1956,7 @@ gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev,
|
|||
break;
|
||||
}
|
||||
|
||||
size = adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
size /= adev->gmc.num_mem_partitions;
|
||||
|
||||
for (i = 0; i < adev->gmc.num_mem_partitions; ++i) {
|
||||
|
|
|
@ -188,6 +188,14 @@ static void sdma_v5_2_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
|
||||
ring->doorbell_index, ring->wptr << 2);
|
||||
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
|
||||
/* SDMA seems to miss doorbells sometimes when powergating kicks in.
|
||||
* Updating the wptr directly will wake it. This is only safe because
|
||||
* we disallow gfxoff in begin_use() and then allow it again in end_use().
|
||||
*/
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR),
|
||||
lower_32_bits(ring->wptr << 2));
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI),
|
||||
upper_32_bits(ring->wptr << 2));
|
||||
} else {
|
||||
DRM_DEBUG("Not using doorbell -- "
|
||||
"mmSDMA%i_GFX_RB_WPTR == 0x%08x "
|
||||
|
@ -1666,6 +1674,10 @@ static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring)
|
|||
* but it shouldn't hurt for other parts since
|
||||
* this GFXOFF will be disallowed anyway when SDMA is
|
||||
* active, this just makes it explicit.
|
||||
* sdma_v5_2_ring_set_wptr() takes advantage of this
|
||||
* to update the wptr because sometimes SDMA seems to miss
|
||||
* doorbells when entering PG. If you remove this, update
|
||||
* sdma_v5_2_ring_set_wptr() as well!
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ static int smu_v13_0_10_mode2_suspend_ip(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].status.hw = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -686,7 +686,7 @@ static void update_mqd_v9_4_3(struct mqd_manager *mm, void *mqd,
|
|||
m = get_mqd(mqd + size * xcc);
|
||||
update_mqd(mm, m, q, minfo);
|
||||
|
||||
update_cu_mask(mm, mqd, minfo, xcc);
|
||||
update_cu_mask(mm, m, minfo, xcc);
|
||||
|
||||
if (q->format == KFD_QUEUE_FORMAT_AQL) {
|
||||
switch (xcc) {
|
||||
|
|
|
@ -154,7 +154,8 @@ const struct dc_plane_status *dc_plane_get_status(
|
|||
if (pipe_ctx->plane_state != plane_state)
|
||||
continue;
|
||||
|
||||
pipe_ctx->plane_state->status.is_flip_pending = false;
|
||||
if (pipe_ctx->plane_state)
|
||||
pipe_ctx->plane_state->status.is_flip_pending = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79,8 +79,8 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin");
|
|||
#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L
|
||||
#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4
|
||||
#define smnPCIE_LC_SPEED_CNTL 0x11140290
|
||||
#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000
|
||||
#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE
|
||||
#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0
|
||||
#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5
|
||||
|
||||
static const int link_width[] = {0, 1, 2, 4, 8, 12, 16};
|
||||
|
||||
|
|
|
@ -2933,7 +2933,7 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
|
|||
|
||||
/* FIXME: Actually do some real error handling here */
|
||||
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
|
||||
if (ret <= 0) {
|
||||
if (ret < 0) {
|
||||
drm_err(mgr->dev, "Sending link address failed with %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
@ -2985,7 +2985,7 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
|
|||
mutex_unlock(&mgr->lock);
|
||||
|
||||
out:
|
||||
if (ret <= 0)
|
||||
if (ret < 0)
|
||||
mstb->link_address_sent = false;
|
||||
kfree(txmsg);
|
||||
return ret < 0 ? ret : changed;
|
||||
|
|
|
@ -4374,6 +4374,8 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
|
|||
!intel_dp_mst_is_master_trans(crtc_state))
|
||||
continue;
|
||||
|
||||
intel_dp->link_trained = false;
|
||||
|
||||
intel_dp_check_frl_training(intel_dp);
|
||||
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
|
||||
intel_dp_start_link_train(intel_dp, crtc_state);
|
||||
|
|
|
@ -114,10 +114,24 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
|
|||
return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1;
|
||||
}
|
||||
|
||||
static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
||||
static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
|
||||
{
|
||||
return intel_dp->lttpr_common_caps[DP_PHY_REPEATER_MODE -
|
||||
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] ==
|
||||
DP_PHY_REPEATER_MODE_TRANSPARENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the LTTPR common capabilities and switch the LTTPR PHYs to
|
||||
* non-transparent mode if this is supported. Preserve the
|
||||
* transparent/non-transparent mode on an active link.
|
||||
*
|
||||
* Return the number of detected LTTPRs in non-transparent mode or 0 if the
|
||||
* LTTPRs are in transparent mode or the detection failed.
|
||||
*/
|
||||
static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
||||
{
|
||||
int lttpr_count;
|
||||
int i;
|
||||
|
||||
if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd))
|
||||
return 0;
|
||||
|
@ -131,6 +145,19 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
|
|||
if (lttpr_count == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Don't change the mode on an active link, to prevent a loss of link
|
||||
* synchronization. See DP Standard v2.0 3.6.7. about the LTTPR
|
||||
* resetting its internal state when the mode is changed from
|
||||
* non-transparent to transparent.
|
||||
*/
|
||||
if (intel_dp->link_trained) {
|
||||
if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp))
|
||||
goto out_reset_lttpr_count;
|
||||
|
||||
return lttpr_count;
|
||||
}
|
||||
|
||||
/*
|
||||
* See DP Standard v2.0 3.6.6.1. about the explicit disabling of
|
||||
* non-transparent mode and the disable->enable non-transparent mode
|
||||
|
@ -151,11 +178,25 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
|
|||
"Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n");
|
||||
|
||||
intel_dp_set_lttpr_transparent_mode(intel_dp, true);
|
||||
intel_dp_reset_lttpr_count(intel_dp);
|
||||
|
||||
return 0;
|
||||
goto out_reset_lttpr_count;
|
||||
}
|
||||
|
||||
return lttpr_count;
|
||||
|
||||
out_reset_lttpr_count:
|
||||
intel_dp_reset_lttpr_count(intel_dp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
||||
{
|
||||
int lttpr_count;
|
||||
int i;
|
||||
|
||||
lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd);
|
||||
|
||||
for (i = 0; i < lttpr_count; i++)
|
||||
intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i));
|
||||
|
||||
|
@ -1353,10 +1394,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
|
|||
{
|
||||
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||
bool passed;
|
||||
|
||||
/*
|
||||
* TODO: Reiniting LTTPRs here won't be needed once proper connector
|
||||
* HW state readout is added.
|
||||
* Reinit the LTTPRs here to ensure that they are switched to
|
||||
* non-transparent mode. During an earlier LTTPR detection this
|
||||
* could've been prevented by an active link.
|
||||
*/
|
||||
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
|
||||
|
||||
|
|
|
@ -3320,11 +3320,7 @@ static void remove_from_engine(struct i915_request *rq)
|
|||
|
||||
static bool can_preempt(struct intel_engine_cs *engine)
|
||||
{
|
||||
if (GRAPHICS_VER(engine->i915) > 8)
|
||||
return true;
|
||||
|
||||
/* GPGPU on bdw requires extra w/a; not implemented */
|
||||
return engine->class != RENDER_CLASS;
|
||||
return GRAPHICS_VER(engine->i915) > 8;
|
||||
}
|
||||
|
||||
static void kick_execlists(const struct i915_request *rq, int prio)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: device.h,v 1.67 2024/05/28 09:40:40 kettenis Exp $ */
|
||||
/* $OpenBSD: device.h,v 1.68 2024/08/04 15:30:08 kettenis Exp $ */
|
||||
/* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -231,7 +231,7 @@ void device_register(struct device *, void *);
|
|||
void device_register_wakeup(struct device *);
|
||||
|
||||
int loadfirmware(const char *name, u_char **bufp, size_t *buflen);
|
||||
#define FIRMWARE_MAX 15*1024*1024
|
||||
#define FIRMWARE_MAX 24*1024*1024
|
||||
|
||||
/* compatibility definitions */
|
||||
#define config_found(d, a, p) config_found_sm((d), (a), (p), NULL)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: poll.h,v 1.15 2016/06/07 06:12:37 deraadt Exp $ */
|
||||
/* $OpenBSD: poll.h,v 1.16 2024/08/04 22:28:08 guenther Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Theo de Raadt
|
||||
|
@ -56,7 +56,7 @@ typedef unsigned int nfds_t;
|
|||
#ifndef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
#if __POSIX_VISIBLE >= 202405 || __BSD_VISIBLE
|
||||
#include <sys/_types.h>
|
||||
|
||||
#ifndef _SIGSET_T_DEFINED_
|
||||
|
@ -80,8 +80,8 @@ struct timespec {
|
|||
|
||||
__BEGIN_DECLS
|
||||
int poll(struct pollfd[], nfds_t, int);
|
||||
#if __BSD_VISIBLE
|
||||
int ppoll(struct pollfd[], nfds_t, const struct timespec *, const sigset_t *);
|
||||
#if __POSIX_VISIBLE >= 202405 || __BSD_VISIBLE
|
||||
int ppoll(struct pollfd[], nfds_t, const struct timespec * __restrict, const sigset_t * __restrict);
|
||||
#endif /* __BSD_VISIBLE */
|
||||
__END_DECLS
|
||||
#endif /* _KERNEL */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue