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: 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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue