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:
Arnd Bergmann 2023-12-22 10:41:36 +00:00
commit 60cc77704e
3 changed files with 137 additions and 36 deletions

View File

@ -3,7 +3,7 @@ What: /sys/devices/platform/HISI04Bx:00/chipX/linked_full_lane
What: /sys/devices/platform/HISI04Bx:00/chipX/crc_err_cnt What: /sys/devices/platform/HISI04Bx:00/chipX/crc_err_cnt
Date: November 2023 Date: November 2023
KernelVersion: 6.6 KernelVersion: 6.6
Contact: Huisong Li <lihuisong@huawei.org> Contact: Huisong Li <lihuisong@huawei.com>
Description: Description:
The /sys/devices/platform/HISI04Bx:00/chipX/ directory The /sys/devices/platform/HISI04Bx:00/chipX/ directory
contains read-only attributes exposing some summarization 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 What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/crc_err_cnt
Date: November 2023 Date: November 2023
KernelVersion: 6.6 KernelVersion: 6.6
Contact: Huisong Li <lihuisong@huawei.org> Contact: Huisong Li <lihuisong@huawei.com>
Description: Description:
The /sys/devices/platform/HISI04Bx:00/chipX/dieY/ directory The /sys/devices/platform/HISI04Bx:00/chipX/dieY/ directory
contains read-only attributes exposing some summarization 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 What: /sys/devices/platform/HISI04Bx:00/chipX/dieY/hccsN/crc_err_cnt
Date: November 2023 Date: November 2023
KernelVersion: 6.6 KernelVersion: 6.6
Contact: Huisong Li <lihuisong@huawei.org> Contact: Huisong Li <lihuisong@huawei.com>
Description: Description:
The /sys/devices/platform/HISI04Bx/chipX/dieX/hccsN/ directory The /sys/devices/platform/HISI04Bx/chipX/dieX/hccsN/ directory
contains read-only attributes exposing information about contains read-only attributes exposing information about

View File

@ -85,8 +85,10 @@ static int hccs_get_pcc_chan_id(struct hccs_dev *hdev)
struct hccs_register_ctx ctx = {0}; struct hccs_register_ctx ctx = {0};
acpi_status status; 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; return -ENODEV;
}
ctx.dev = hdev->dev; ctx.dev = hdev->dev;
status = acpi_walk_resources(handle, METHOD_NAME__CRS, 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); *(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) static void hccs_unregister_pcc_channel(struct hccs_dev *hdev)
{ {
struct hccs_mbox_client_info *cl_info = &hdev->cl_info; 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->tx_block = false;
cl->knows_txdone = true; cl->knows_txdone = true;
cl->tx_done = hccs_chan_tx_done; 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); pcc_chan = pcc_mbox_request_channel(cl, hdev->chan_id);
if (IS_ERR(pcc_chan)) { if (IS_ERR(pcc_chan)) {
dev_err(dev, "PPC channel request failed.\n"); 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 = cl_info->deadline_us =
HCCS_PCC_CMD_WAIT_RETRIES_NUM * pcc_chan->latency; 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"); dev_err(dev, "PCC IRQ in PCCT is enabled.\n");
rc = -EINVAL; rc = -EINVAL;
goto err_mbx_channel_free; 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) { if (pcc_chan->shmem_base_addr) {
cl_info->pcc_comm_addr = ioremap(pcc_chan->shmem_base_addr, cl_info->pcc_comm_addr = ioremap(pcc_chan->shmem_base_addr,
pcc_chan->shmem_size); pcc_chan->shmem_size);
if (!cl_info->pcc_comm_addr) { 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); hdev->chan_id);
rc = -ENOMEM; rc = -ENOMEM;
goto err_mbx_channel_free; goto err_mbx_channel_free;
@ -170,7 +189,7 @@ out:
return rc; 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 hccs_mbox_client_info *cl_info = &hdev->cl_info;
struct acpi_pcct_shared_memory __iomem *comm_base = 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; 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, static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
struct hccs_desc *desc) struct hccs_desc *desc)
{ {
const struct hccs_verspecific_data *verspec_data = hdev->verspec_data;
struct hccs_mbox_client_info *cl_info = &hdev->cl_info; 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 hccs_fw_inner_head *fw_inner_head;
struct acpi_pcct_shared_memory tmp = {0}; void __iomem *comm_space;
u16 comm_space_size; u16 space_size;
int ret; int ret;
/* Write signature for this subspace */ comm_space = cl_info->pcc_comm_addr + verspec_data->shared_mem_size;
tmp.signature = PCC_SIGNATURE | hdev->chan_id; space_size = HCCS_PCC_SHARE_MEM_BYTES - verspec_data->shared_mem_size;
/* Write to the shared command region */ verspec_data->fill_pcc_shared_mem(hdev, cmd, desc,
tmp.command = cmd; comm_space, space_size);
/* Clear cmd complete bit */ if (verspec_data->has_txdone_irq)
tmp.status = 0; reinit_completion(&cl_info->done);
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);
/* Ring doorbell */ /* Ring doorbell */
ret = mbox_send_message(cl_info->mbox_chan, &cmd); 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; goto end;
} }
/* Wait for completion */ ret = verspec_data->wait_cmd_complete(hdev);
ret = hccs_check_chan_cmd_complete(hdev);
if (ret) if (ret)
goto end; goto end;
/* Copy response data */ /* 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; fw_inner_head = &desc->rsp.fw_inner_head;
if (fw_inner_head->retStatus) { if (fw_inner_head->retStatus) {
dev_err(hdev->dev, "Execute PCC command failed, error code = %u.\n", 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: 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; return ret;
} }
@ -527,7 +592,6 @@ out:
static int hccs_query_all_port_info_on_platform(struct hccs_dev *hdev) static int hccs_query_all_port_info_on_platform(struct hccs_dev *hdev)
{ {
struct device *dev = hdev->dev; struct device *dev = hdev->dev;
struct hccs_chip_info *chip; struct hccs_chip_info *chip;
struct hccs_die_info *die; struct hccs_die_info *die;
@ -1097,7 +1161,7 @@ static int hccs_create_hccs_dir(struct hccs_dev *hdev,
int ret; int ret;
ret = kobject_init_and_add(&port->kobj, &hccs_port_type, 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) { if (ret) {
kobject_put(&port->kobj); kobject_put(&port->kobj);
return ret; return ret;
@ -1115,7 +1179,7 @@ static int hccs_create_die_dir(struct hccs_dev *hdev,
u16 i; u16 i;
ret = kobject_init_and_add(&die->kobj, &hccs_die_type, 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) { if (ret) {
kobject_put(&die->kobj); kobject_put(&die->kobj);
return ret; return ret;
@ -1125,7 +1189,7 @@ static int hccs_create_die_dir(struct hccs_dev *hdev,
port = &die->ports[i]; port = &die->ports[i];
ret = hccs_create_hccs_dir(hdev, die, port); ret = hccs_create_hccs_dir(hdev, die, port);
if (ret) { 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); port->port_id);
goto err; goto err;
} }
@ -1147,7 +1211,7 @@ static int hccs_create_chip_dir(struct hccs_dev *hdev,
u16 id; u16 id;
ret = kobject_init_and_add(&chip->kobj, &hccs_chip_type, 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) { if (ret) {
kobject_put(&chip->kobj); kobject_put(&chip->kobj);
return ret; return ret;
@ -1178,7 +1242,7 @@ static int hccs_create_topo_dirs(struct hccs_dev *hdev)
chip = &hdev->chips[id]; chip = &hdev->chips[id];
ret = hccs_create_chip_dir(hdev, chip); ret = hccs_create_chip_dir(hdev, chip);
if (ret) { 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; goto err;
} }
} }
@ -1212,6 +1276,11 @@ static int hccs_probe(struct platform_device *pdev)
hdev->dev = &pdev->dev; hdev->dev = &pdev->dev;
platform_set_drvdata(pdev, hdev); 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); mutex_init(&hdev->lock);
rc = hccs_get_pcc_chan_id(hdev); rc = hccs_get_pcc_chan_id(hdev);
if (rc) if (rc)
@ -1248,9 +1317,26 @@ static void hccs_remove(struct platform_device *pdev)
hccs_unregister_pcc_channel(hdev); 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[] = { 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); MODULE_DEVICE_TABLE(acpi, hccs_acpi_match);

View File

@ -51,11 +51,26 @@ struct hccs_mbox_client_info {
struct pcc_mbox_chan *pcc_chan; struct pcc_mbox_chan *pcc_chan;
u64 deadline_us; u64 deadline_us;
void __iomem *pcc_comm_addr; 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 hccs_dev {
struct device *dev; struct device *dev;
struct acpi_device *acpi_dev; struct acpi_device *acpi_dev;
const struct hccs_verspecific_data *verspec_data;
u64 caps; u64 caps;
u8 chip_num; u8 chip_num;
struct hccs_chip_info *chips; struct hccs_chip_info *chips;