Merge branch 'for-6.3/cxl-autodetect-fixes' into for-6.4/cxl
Pick up late v6.3 fixes for v6.4.
This commit is contained in:
Коммит
ca899f4021
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
|
||||
#include <linux/io-64-nonatomic-hi-lo.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -93,8 +92,9 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
|
|||
|
||||
cxl_probe_component_regs(&port->dev, crb, &map.component_map);
|
||||
if (!map.component_map.hdm_decoder.valid) {
|
||||
dev_err(&port->dev, "HDM decoder registers invalid\n");
|
||||
return -ENXIO;
|
||||
dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
|
||||
/* unique error code to indicate no HDM decoder capability */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return cxl_map_component_regs(&port->dev, regs, &map,
|
||||
|
@ -130,6 +130,14 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
|
|||
*/
|
||||
for (i = 0; i < cxlhdm->decoder_count; i++) {
|
||||
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
|
||||
dev_dbg(&info->port->dev,
|
||||
"decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n",
|
||||
info->port->id, i,
|
||||
FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl),
|
||||
readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)),
|
||||
readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)),
|
||||
readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)),
|
||||
readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i)));
|
||||
if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
|
||||
return false;
|
||||
}
|
||||
|
@ -269,8 +277,11 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
|
|||
|
||||
lockdep_assert_held_write(&cxl_dpa_rwsem);
|
||||
|
||||
if (!len)
|
||||
goto success;
|
||||
if (!len) {
|
||||
dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
|
||||
port->id, cxled->cxld.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cxled->dpa_res) {
|
||||
dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
|
||||
|
@ -323,7 +334,6 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
|
|||
cxled->mode = CXL_DECODER_MIXED;
|
||||
}
|
||||
|
||||
success:
|
||||
port->hdm_end++;
|
||||
get_device(&cxled->cxld.dev);
|
||||
return 0;
|
||||
|
@ -783,8 +793,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
|
|||
int *target_map, void __iomem *hdm, int which,
|
||||
u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
|
||||
{
|
||||
u64 size, base, skip, dpa_size, lo, hi;
|
||||
struct cxl_endpoint_decoder *cxled;
|
||||
u64 size, base, skip, dpa_size;
|
||||
bool committed;
|
||||
u32 remainder;
|
||||
int i, rc;
|
||||
|
@ -799,8 +809,12 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
|
|||
which, info);
|
||||
|
||||
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
|
||||
base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
|
||||
size = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
|
||||
lo = readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
|
||||
hi = readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(which));
|
||||
base = (hi << 32) + lo;
|
||||
lo = readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
|
||||
hi = readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(which));
|
||||
size = (hi << 32) + lo;
|
||||
committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED);
|
||||
cxld->commit = cxl_decoder_commit;
|
||||
cxld->reset = cxl_decoder_reset;
|
||||
|
@ -833,6 +847,13 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
|
|||
port->id, cxld->id);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
dev_warn(&port->dev,
|
||||
"decoder%d.%d: Committed with zero size\n",
|
||||
port->id, cxld->id);
|
||||
return -ENXIO;
|
||||
}
|
||||
port->commit_end = cxld->id;
|
||||
} else {
|
||||
/* unless / until type-2 drivers arrive, assume type-3 */
|
||||
|
@ -855,9 +876,14 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
dev_dbg(&port->dev, "decoder%d.%d: range: %#llx-%#llx iw: %d ig: %d\n",
|
||||
port->id, cxld->id, cxld->hpa_range.start, cxld->hpa_range.end,
|
||||
cxld->interleave_ways, cxld->interleave_granularity);
|
||||
|
||||
if (!info) {
|
||||
target_list.value =
|
||||
ioread64_hi_lo(hdm + CXL_HDM_DECODER0_TL_LOW(which));
|
||||
lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which));
|
||||
hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
|
||||
target_list.value = (hi << 32) + lo;
|
||||
for (i = 0; i < cxld->interleave_ways; i++)
|
||||
target_map[i] = target_list.target_id[i];
|
||||
|
||||
|
@ -874,7 +900,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
|
|||
port->id, cxld->id, size, cxld->interleave_ways);
|
||||
return -ENXIO;
|
||||
}
|
||||
skip = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
|
||||
lo = readl(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
|
||||
hi = readl(hdm + CXL_HDM_DECODER0_SKIP_HIGH(which));
|
||||
skip = (hi << 32) + lo;
|
||||
cxled = to_cxl_endpoint_decoder(&cxld->dev);
|
||||
rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip);
|
||||
if (rc) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/ktime.h>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/memregion.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
|
|
@ -66,14 +66,22 @@ static int cxl_switch_port_probe(struct cxl_port *port)
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (rc == 1)
|
||||
return devm_cxl_add_passthrough_decoder(port);
|
||||
|
||||
cxlhdm = devm_cxl_setup_hdm(port, NULL);
|
||||
if (IS_ERR(cxlhdm))
|
||||
return PTR_ERR(cxlhdm);
|
||||
if (!IS_ERR(cxlhdm))
|
||||
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
|
||||
|
||||
return devm_cxl_enumerate_decoders(cxlhdm, NULL);
|
||||
if (PTR_ERR(cxlhdm) != -ENODEV) {
|
||||
dev_err(&port->dev, "Failed to map HDM decoder capability\n");
|
||||
return PTR_ERR(cxlhdm);
|
||||
}
|
||||
|
||||
if (rc == 1) {
|
||||
dev_dbg(&port->dev, "Fallback to passthrough decoder\n");
|
||||
return devm_cxl_add_passthrough_decoder(port);
|
||||
}
|
||||
|
||||
dev_err(&port->dev, "HDM decoder capability not found\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static int cxl_endpoint_port_probe(struct cxl_port *port)
|
||||
|
|
Загрузка…
Ссылка в новой задаче