HiSilicon driver updates for v6.8
- Add support for the platform with PCC type3 and interrupt ack - Few cleanups and improvements: correct the format of some strings and domain typo, add failure log -----BEGIN PGP SIGNATURE----- iQJJBAABCgAzFiEEQeMYD8qOQTc1R/snC8hXbtmJZlwFAmVxdIEVHHh1d2VpNUBo aXNpbGljb24uY29tAAoJEAvIV27ZiWZczqoQALBHanmpdkiXcI6ylgaJ6F88Lq7P p8mGYQojwWBU7X68bQax98CN8dHYD/v2xA1+3cCZrtW5+ZoasTlmF3WS8H8CrauQ 8Kz5Tgvltd1dLRmEX7/vtWoktnMbDZ6CotC4GDsOicyC0l8R03z01CLZHXbqK0Hl d98n5h+GeoUiryzgzRfomqrpCDj7+zeOhSCcQxnLi7U9WGSjJk7hPciVqZ/dTeG8 ++gieImv0CVEhi9PIl4el2468YuMtoP0HNItLmlsOdtH84Vs7SwUNhg89O3pPHVH uQX7IfJHovRR1iK1PscX8h8ZQGIIcrxTq57S7mknJonOQYgwCoaEIBSWORpoQo5H QddRZ4bv5XXUYl4cOum+eCj2ZUB58eawqL1q+t5d7Nf0awiZver8lrdgSPA51n5j Iu/V0oU6il3us+ZXSO9RA5Zzlu6sblB1G+/NKragQnjtn0CcIQAb/gf0AXhg04ug /JCZv19UEKBQ6yLS+1qtMQmLm7G5NqzbhPVhX0YtX/WySYn47f0AEvKeZFGnckia Yn/bcdJ6PJqSxU0lFLrluBESb35NCXpzQDkfxbjAyfIlhDyp/0JStED/TTtd3c8Q eBVo1aDb+CNjvl+17xZ6udD5j/0Y+kf2z8h9+x0tvmHOuz/4zFY7/0jip34u/v/1 M+bxo3wE3Z/91QXc =hJz1 -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmWFZ+AACgkQYKtH/8kJ UicjMhAAqNSLRbXjQ1z9b0IpZYrQ5+VBUgoSLKYSA7u0ae20sh7B1fdW7xlejDK+ lrwg1/EICLxSPbJU1oLC8ExuIWpCcgQB//4Bjd24sVb6NIw9QwktPwcJPt2RX0be /nIgImEfbiwRJF+xJRaCeuNf7lauaMZTfj6kShT3OEY5osC4Jq+SM1k3VUQ67jsP h1HoOArbx9tHzsunvVtiucyXLS26l53cMjOIUvpTJi3+rbbJ7Tuvwi51sJMbGUAg vl0b5Zf+rlhlLOcEX53PkheYeXiFDlACc1FTyeaN8f2t3XFHhzV05TIUcUFbYnGb NrQw3eKvnMvZu2wOp4i0E0SJ5gb4inSMVgkDPfqmkXIpX9c3p8rQDxdtOotvOYkD aooe38cv4BiwFL2DK2qLGF7yh1jVvZ+P6ASWZ6Ub7SNZhvuOxqno97+2qpMiBrhw EGEW26vAgxixXhIsWS8YgGLAUNG3VCdzUQO9SK+jMUJodV4H6XP0CD4phBn9/2wx lSO29aA6hi0R52O2lJjq1Y/wqh8/FGoluMWAVsLa2f+o9UeABxeu9T5lblatuwJ/ FDQo01F/HcDAiJfudKsNEb5xHglCRi4I3xCsLogbVEoIJOT7jaYpZ26h0xIX9lhc wVVjjVggfjiPJVkipotNg6zoRbQrz3o+i41GJIyI0NBzXO+AzwI= =cjVE -----END PGP SIGNATURE----- Merge tag 'hisi-drivers-for-6.8' of https://github.com/hisilicon/linux-hisi into soc/drivers HiSilicon driver updates for v6.8 - Add support for the platform with PCC type3 and interrupt ack - Few cleanups and improvements: correct the format of some strings and domain typo, add failure log * tag 'hisi-drivers-for-6.8' of https://github.com/hisilicon/linux-hisi: soc: hisilicon: kunpeng_hccs: Support the platform with PCC type3 and interrupt ack doc: kunpeng_hccs: Fix incorrect email domain name soc: hisilicon: kunpeng_hccs: Remove an unused blank line soc: hisilicon: kunpeng_hccs: Add failure log for no _CRS method soc: hisilicon: kunpeng_hccs: Fix some incorrect format strings Link: https://lore.kernel.org/r/6572C41B.6050703@hisilicon.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
60cc77704e
@ -3,7 +3,7 @@ What: /sys/devices/platform/HISI04Bx:00/chipX/linked_full_lane
|
||||
What: /sys/devices/platform/HISI04Bx:00/chipX/crc_err_cnt
|
||||
Date: November 2023
|
||||
KernelVersion: 6.6
|
||||
Contact: Huisong Li <lihuisong@huawei.org>
|
||||
Contact: Huisong Li <lihuisong@huawei.com>
|
||||
Description:
|
||||
The /sys/devices/platform/HISI04Bx:00/chipX/ directory
|
||||
contains read-only attributes exposing some summarization
|
||||
@ -26,7 +26,7 @@ What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/linked_full_lane
|
||||
What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/crc_err_cnt
|
||||
Date: November 2023
|
||||
KernelVersion: 6.6
|
||||
Contact: Huisong Li <lihuisong@huawei.org>
|
||||
Contact: Huisong Li <lihuisong@huawei.com>
|
||||
Description:
|
||||
The /sys/devices/platform/HISI04Bx:00/chipX/dieY/ directory
|
||||
contains read-only attributes exposing some summarization
|
||||
@ -54,7 +54,7 @@ What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/hccsN/lane_mask
|
||||
What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/hccsN/crc_err_cnt
|
||||
Date: November 2023
|
||||
KernelVersion: 6.6
|
||||
Contact: Huisong Li <lihuisong@huawei.org>
|
||||
Contact: Huisong Li <lihuisong@huawei.com>
|
||||
Description:
|
||||
The /sys/devices/platform/HISI04Bx/chipX/dieX/hccsN/ directory
|
||||
contains read-only attributes exposing information about
|
||||
|
@ -85,8 +85,10 @@ static int hccs_get_pcc_chan_id(struct hccs_dev *hdev)
|
||||
struct hccs_register_ctx ctx = {0};
|
||||
acpi_status status;
|
||||
|
||||
if (!acpi_has_method(handle, METHOD_NAME__CRS))
|
||||
if (!acpi_has_method(handle, METHOD_NAME__CRS)) {
|
||||
dev_err(hdev->dev, "No _CRS method.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ctx.dev = hdev->dev;
|
||||
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
|
||||
@ -108,6 +110,14 @@ static void hccs_chan_tx_done(struct mbox_client *cl, void *msg, int ret)
|
||||
*(u8 *)msg, ret);
|
||||
}
|
||||
|
||||
static void hccs_pcc_rx_callback(struct mbox_client *cl, void *mssg)
|
||||
{
|
||||
struct hccs_mbox_client_info *cl_info =
|
||||
container_of(cl, struct hccs_mbox_client_info, client);
|
||||
|
||||
complete(&cl_info->done);
|
||||
}
|
||||
|
||||
static void hccs_unregister_pcc_channel(struct hccs_dev *hdev)
|
||||
{
|
||||
struct hccs_mbox_client_info *cl_info = &hdev->cl_info;
|
||||
@ -129,6 +139,9 @@ static int hccs_register_pcc_channel(struct hccs_dev *hdev)
|
||||
cl->tx_block = false;
|
||||
cl->knows_txdone = true;
|
||||
cl->tx_done = hccs_chan_tx_done;
|
||||
cl->rx_callback = hdev->verspec_data->rx_callback;
|
||||
init_completion(&cl_info->done);
|
||||
|
||||
pcc_chan = pcc_mbox_request_channel(cl, hdev->chan_id);
|
||||
if (IS_ERR(pcc_chan)) {
|
||||
dev_err(dev, "PPC channel request failed.\n");
|
||||
@ -145,17 +158,23 @@ static int hccs_register_pcc_channel(struct hccs_dev *hdev)
|
||||
*/
|
||||
cl_info->deadline_us =
|
||||
HCCS_PCC_CMD_WAIT_RETRIES_NUM * pcc_chan->latency;
|
||||
if (cl_info->mbox_chan->mbox->txdone_irq) {
|
||||
if (!hdev->verspec_data->has_txdone_irq &&
|
||||
cl_info->mbox_chan->mbox->txdone_irq) {
|
||||
dev_err(dev, "PCC IRQ in PCCT is enabled.\n");
|
||||
rc = -EINVAL;
|
||||
goto err_mbx_channel_free;
|
||||
} else if (hdev->verspec_data->has_txdone_irq &&
|
||||
!cl_info->mbox_chan->mbox->txdone_irq) {
|
||||
dev_err(dev, "PCC IRQ in PCCT isn't supported.\n");
|
||||
rc = -EINVAL;
|
||||
goto err_mbx_channel_free;
|
||||
}
|
||||
|
||||
if (pcc_chan->shmem_base_addr) {
|
||||
cl_info->pcc_comm_addr = ioremap(pcc_chan->shmem_base_addr,
|
||||
pcc_chan->shmem_size);
|
||||
if (!cl_info->pcc_comm_addr) {
|
||||
dev_err(dev, "Failed to ioremap PCC communication region for channel-%d.\n",
|
||||
dev_err(dev, "Failed to ioremap PCC communication region for channel-%u.\n",
|
||||
hdev->chan_id);
|
||||
rc = -ENOMEM;
|
||||
goto err_mbx_channel_free;
|
||||
@ -170,7 +189,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev)
|
||||
static int hccs_wait_cmd_complete_by_poll(struct hccs_dev *hdev)
|
||||
{
|
||||
struct hccs_mbox_client_info *cl_info = &hdev->cl_info;
|
||||
struct acpi_pcct_shared_memory __iomem *comm_base =
|
||||
@ -192,30 +211,74 @@ static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hccs_wait_cmd_complete_by_irq(struct hccs_dev *hdev)
|
||||
{
|
||||
struct hccs_mbox_client_info *cl_info = &hdev->cl_info;
|
||||
|
||||
if (!wait_for_completion_timeout(&cl_info->done,
|
||||
usecs_to_jiffies(cl_info->deadline_us))) {
|
||||
dev_err(hdev->dev, "PCC command executed timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void hccs_fill_pcc_shared_mem_region(struct hccs_dev *hdev,
|
||||
u8 cmd,
|
||||
struct hccs_desc *desc,
|
||||
void __iomem *comm_space,
|
||||
u16 space_size)
|
||||
{
|
||||
struct acpi_pcct_shared_memory tmp = {
|
||||
.signature = PCC_SIGNATURE | hdev->chan_id,
|
||||
.command = cmd,
|
||||
.status = 0,
|
||||
};
|
||||
|
||||
memcpy_toio(hdev->cl_info.pcc_comm_addr, (void *)&tmp,
|
||||
sizeof(struct acpi_pcct_shared_memory));
|
||||
|
||||
/* Copy the message to the PCC comm space */
|
||||
memcpy_toio(comm_space, (void *)desc, space_size);
|
||||
}
|
||||
|
||||
static inline void hccs_fill_ext_pcc_shared_mem_region(struct hccs_dev *hdev,
|
||||
u8 cmd,
|
||||
struct hccs_desc *desc,
|
||||
void __iomem *comm_space,
|
||||
u16 space_size)
|
||||
{
|
||||
struct acpi_pcct_ext_pcc_shared_memory tmp = {
|
||||
.signature = PCC_SIGNATURE | hdev->chan_id,
|
||||
.flags = PCC_CMD_COMPLETION_NOTIFY,
|
||||
.length = HCCS_PCC_SHARE_MEM_BYTES,
|
||||
.command = cmd,
|
||||
};
|
||||
|
||||
memcpy_toio(hdev->cl_info.pcc_comm_addr, (void *)&tmp,
|
||||
sizeof(struct acpi_pcct_ext_pcc_shared_memory));
|
||||
|
||||
/* Copy the message to the PCC comm space */
|
||||
memcpy_toio(comm_space, (void *)desc, space_size);
|
||||
}
|
||||
|
||||
static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
|
||||
struct hccs_desc *desc)
|
||||
{
|
||||
const struct hccs_verspecific_data *verspec_data = hdev->verspec_data;
|
||||
struct hccs_mbox_client_info *cl_info = &hdev->cl_info;
|
||||
void __iomem *comm_space = cl_info->pcc_comm_addr +
|
||||
sizeof(struct acpi_pcct_shared_memory);
|
||||
struct hccs_fw_inner_head *fw_inner_head;
|
||||
struct acpi_pcct_shared_memory tmp = {0};
|
||||
u16 comm_space_size;
|
||||
void __iomem *comm_space;
|
||||
u16 space_size;
|
||||
int ret;
|
||||
|
||||
/* Write signature for this subspace */
|
||||
tmp.signature = PCC_SIGNATURE | hdev->chan_id;
|
||||
/* Write to the shared command region */
|
||||
tmp.command = cmd;
|
||||
/* Clear cmd complete bit */
|
||||
tmp.status = 0;
|
||||
memcpy_toio(cl_info->pcc_comm_addr, (void *)&tmp,
|
||||
sizeof(struct acpi_pcct_shared_memory));
|
||||
|
||||
/* Copy the message to the PCC comm space */
|
||||
comm_space_size = HCCS_PCC_SHARE_MEM_BYTES -
|
||||
sizeof(struct acpi_pcct_shared_memory);
|
||||
memcpy_toio(comm_space, (void *)desc, comm_space_size);
|
||||
comm_space = cl_info->pcc_comm_addr + verspec_data->shared_mem_size;
|
||||
space_size = HCCS_PCC_SHARE_MEM_BYTES - verspec_data->shared_mem_size;
|
||||
verspec_data->fill_pcc_shared_mem(hdev, cmd, desc,
|
||||
comm_space, space_size);
|
||||
if (verspec_data->has_txdone_irq)
|
||||
reinit_completion(&cl_info->done);
|
||||
|
||||
/* Ring doorbell */
|
||||
ret = mbox_send_message(cl_info->mbox_chan, &cmd);
|
||||
@ -225,13 +288,12 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Wait for completion */
|
||||
ret = hccs_check_chan_cmd_complete(hdev);
|
||||
ret = verspec_data->wait_cmd_complete(hdev);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
/* Copy response data */
|
||||
memcpy_fromio((void *)desc, comm_space, comm_space_size);
|
||||
memcpy_fromio((void *)desc, comm_space, space_size);
|
||||
fw_inner_head = &desc->rsp.fw_inner_head;
|
||||
if (fw_inner_head->retStatus) {
|
||||
dev_err(hdev->dev, "Execute PCC command failed, error code = %u.\n",
|
||||
@ -240,7 +302,10 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
|
||||
}
|
||||
|
||||
end:
|
||||
mbox_client_txdone(cl_info->mbox_chan, ret);
|
||||
if (verspec_data->has_txdone_irq)
|
||||
mbox_chan_txdone(cl_info->mbox_chan, ret);
|
||||
else
|
||||
mbox_client_txdone(cl_info->mbox_chan, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -527,7 +592,6 @@ out:
|
||||
|
||||
static int hccs_query_all_port_info_on_platform(struct hccs_dev *hdev)
|
||||
{
|
||||
|
||||
struct device *dev = hdev->dev;
|
||||
struct hccs_chip_info *chip;
|
||||
struct hccs_die_info *die;
|
||||
@ -1097,7 +1161,7 @@ static int hccs_create_hccs_dir(struct hccs_dev *hdev,
|
||||
int ret;
|
||||
|
||||
ret = kobject_init_and_add(&port->kobj, &hccs_port_type,
|
||||
&die->kobj, "hccs%d", port->port_id);
|
||||
&die->kobj, "hccs%u", port->port_id);
|
||||
if (ret) {
|
||||
kobject_put(&port->kobj);
|
||||
return ret;
|
||||
@ -1115,7 +1179,7 @@ static int hccs_create_die_dir(struct hccs_dev *hdev,
|
||||
u16 i;
|
||||
|
||||
ret = kobject_init_and_add(&die->kobj, &hccs_die_type,
|
||||
&chip->kobj, "die%d", die->die_id);
|
||||
&chip->kobj, "die%u", die->die_id);
|
||||
if (ret) {
|
||||
kobject_put(&die->kobj);
|
||||
return ret;
|
||||
@ -1125,7 +1189,7 @@ static int hccs_create_die_dir(struct hccs_dev *hdev,
|
||||
port = &die->ports[i];
|
||||
ret = hccs_create_hccs_dir(hdev, die, port);
|
||||
if (ret) {
|
||||
dev_err(hdev->dev, "create hccs%d dir failed.\n",
|
||||
dev_err(hdev->dev, "create hccs%u dir failed.\n",
|
||||
port->port_id);
|
||||
goto err;
|
||||
}
|
||||
@ -1147,7 +1211,7 @@ static int hccs_create_chip_dir(struct hccs_dev *hdev,
|
||||
u16 id;
|
||||
|
||||
ret = kobject_init_and_add(&chip->kobj, &hccs_chip_type,
|
||||
&hdev->dev->kobj, "chip%d", chip->chip_id);
|
||||
&hdev->dev->kobj, "chip%u", chip->chip_id);
|
||||
if (ret) {
|
||||
kobject_put(&chip->kobj);
|
||||
return ret;
|
||||
@ -1178,7 +1242,7 @@ static int hccs_create_topo_dirs(struct hccs_dev *hdev)
|
||||
chip = &hdev->chips[id];
|
||||
ret = hccs_create_chip_dir(hdev, chip);
|
||||
if (ret) {
|
||||
dev_err(hdev->dev, "init chip%d dir failed!\n", id);
|
||||
dev_err(hdev->dev, "init chip%u dir failed!\n", id);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -1212,6 +1276,11 @@ static int hccs_probe(struct platform_device *pdev)
|
||||
hdev->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, hdev);
|
||||
|
||||
/*
|
||||
* Here would never be failure as the driver and device has been matched.
|
||||
*/
|
||||
hdev->verspec_data = acpi_device_get_match_data(hdev->dev);
|
||||
|
||||
mutex_init(&hdev->lock);
|
||||
rc = hccs_get_pcc_chan_id(hdev);
|
||||
if (rc)
|
||||
@ -1248,9 +1317,26 @@ static void hccs_remove(struct platform_device *pdev)
|
||||
hccs_unregister_pcc_channel(hdev);
|
||||
}
|
||||
|
||||
static const struct hccs_verspecific_data hisi04b1_verspec_data = {
|
||||
.rx_callback = NULL,
|
||||
.wait_cmd_complete = hccs_wait_cmd_complete_by_poll,
|
||||
.fill_pcc_shared_mem = hccs_fill_pcc_shared_mem_region,
|
||||
.shared_mem_size = sizeof(struct acpi_pcct_shared_memory),
|
||||
.has_txdone_irq = false,
|
||||
};
|
||||
|
||||
static const struct hccs_verspecific_data hisi04b2_verspec_data = {
|
||||
.rx_callback = hccs_pcc_rx_callback,
|
||||
.wait_cmd_complete = hccs_wait_cmd_complete_by_irq,
|
||||
.fill_pcc_shared_mem = hccs_fill_ext_pcc_shared_mem_region,
|
||||
.shared_mem_size = sizeof(struct acpi_pcct_ext_pcc_shared_memory),
|
||||
.has_txdone_irq = true,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id hccs_acpi_match[] = {
|
||||
{ "HISI04B1"},
|
||||
{ ""},
|
||||
{ "HISI04B1", (unsigned long)&hisi04b1_verspec_data},
|
||||
{ "HISI04B2", (unsigned long)&hisi04b2_verspec_data},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hccs_acpi_match);
|
||||
|
||||
|
@ -51,11 +51,26 @@ struct hccs_mbox_client_info {
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
u64 deadline_us;
|
||||
void __iomem *pcc_comm_addr;
|
||||
struct completion done;
|
||||
};
|
||||
|
||||
struct hccs_desc;
|
||||
|
||||
struct hccs_verspecific_data {
|
||||
void (*rx_callback)(struct mbox_client *cl, void *mssg);
|
||||
int (*wait_cmd_complete)(struct hccs_dev *hdev);
|
||||
void (*fill_pcc_shared_mem)(struct hccs_dev *hdev,
|
||||
u8 cmd, struct hccs_desc *desc,
|
||||
void __iomem *comm_space,
|
||||
u16 space_size);
|
||||
u16 shared_mem_size;
|
||||
bool has_txdone_irq;
|
||||
};
|
||||
|
||||
struct hccs_dev {
|
||||
struct device *dev;
|
||||
struct acpi_device *acpi_dev;
|
||||
const struct hccs_verspecific_data *verspec_data;
|
||||
u64 caps;
|
||||
u8 chip_num;
|
||||
struct hccs_chip_info *chips;
|
||||
|
Loading…
Reference in New Issue
Block a user