Unverified Commit d423f0b8 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4140 backport some patches for kunpeng hccs

Merge Pull Request from: @huangdengdui 
 
backport some patches for kunpeng hccs are as follows:
55d235ebb684b993b3247740c1c8e273f8af4a54 ACPI: PCC: Add PCC shared memory region command and status bitfields
89a4ad1f437c049534891c3d83cd96d7c7debd2a i2c: xgene-slimpro: Migrate to use generic PCC shmem related macros
2cf39b806be74661cc347e99796c97d9f54b7c42 hwmon: (xgene) Migrate to use generic PCC shmem related macros

a46e42c097982e258f89c64c5f52f30994bcfeda soc: kunpeng_hccs: Migrate to use generic PCC shmem related macros
3f40c999de39626f67aa36858801ec2906740125 soc/hisilicon: kunpeng_hccs: Convert to platform remove callback returning void
734add1a278f05db2d5a0b9d280a8bce94ce5eeb soc: hisilicon: kunpeng_hccs: Fix some incorrect format strings
e1e720f3f2c50a6f3440b3684decd7b7c046e111 soc: hisilicon: kunpeng_hccs: Add failure log for no _CRS method
a079f3244563a4c4dc32b0a9bfa0e3e519f3c9ed soc: hisilicon: kunpeng_hccs: Remove an unused blank line
a07d8fc358af5f297b41b2182a5fce710e3c9bd7 doc: kunpeng_hccs: Fix incorrect email domain name
be2f78a8a638e71bbbc2109bc052524143e8f42a soc: hisilicon: kunpeng_hccs: Support the platform with PCC type3 and interrupt ack 
 
Link:https://gitee.com/openeuler/kernel/pulls/4140

 

Reviewed-by: default avatarFred Kimmy <xweikong@163.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 6e0294f9 f11d5c24
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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
+5 −11
Original line number Diff line number Diff line
@@ -57,12 +57,6 @@
	(MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \
	MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type)

/* PCC defines */
#define PCC_SIGNATURE_MASK		0x50424300
#define PCCC_GENERATE_DB_INT		BIT(15)
#define PCCS_CMD_COMPLETE		BIT(0)
#define PCCS_SCI_DOORBEL		BIT(1)
#define PCCS_PLATFORM_NOTIFICATION	BIT(3)
/*
 * Arbitrary retries in case the remote processor is slow to respond
 * to PCC commands
@@ -142,15 +136,15 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)

	/* Write signature for subspace */
	WRITE_ONCE(generic_comm_base->signature,
		   cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
		   cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));

	/* Write to the shared command region */
	WRITE_ONCE(generic_comm_base->command,
		   cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
		   cpu_to_le16(MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));

	/* Flip CMD COMPLETE bit */
	val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
	val &= ~PCCS_CMD_COMPLETE;
	val &= ~PCC_STATUS_CMD_COMPLETE;
	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));

	/* Copy the message to the PCC comm space */
@@ -544,7 +538,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
	msg = generic_comm_base + 1;
	/* Check if platform sends interrupt */
	if (!xgene_word_tst_and_clr(&generic_comm_base->status,
				    PCCS_SCI_DOORBEL))
				    PCC_STATUS_SCI_DOORBELL))
		return;

	/*
@@ -566,7 +560,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
	      TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
		/* Check if platform completes command */
		if (xgene_word_tst_and_clr(&generic_comm_base->status,
					   PCCS_CMD_COMPLETE)) {
					   PCC_STATUS_CMD_COMPLETE)) {
			ctx->sync_msg.msg = ((u32 *)msg)[0];
			ctx->sync_msg.param1 = ((u32 *)msg)[1];
			ctx->sync_msg.param2 = ((u32 *)msg)[2];
+4 −12
Original line number Diff line number Diff line
@@ -91,14 +91,6 @@

#define SLIMPRO_IIC_MSG_DWORD_COUNT			3

/* PCC related defines */
#define PCC_SIGNATURE			0x50424300
#define PCC_STS_CMD_COMPLETE		BIT(0)
#define PCC_STS_SCI_DOORBELL		BIT(1)
#define PCC_STS_ERR			BIT(2)
#define PCC_STS_PLAT_NOTIFY		BIT(3)
#define PCC_CMD_GENERATE_DB_INT		BIT(15)

struct slimpro_i2c_dev {
	struct i2c_adapter adapter;
	struct device *dev;
@@ -160,11 +152,11 @@ static void slimpro_i2c_pcc_rx_cb(struct mbox_client *cl, void *msg)

	/* Check if platform sends interrupt */
	if (!xgene_word_tst_and_clr(&generic_comm_base->status,
				    PCC_STS_SCI_DOORBELL))
				    PCC_STATUS_SCI_DOORBELL))
		return;

	if (xgene_word_tst_and_clr(&generic_comm_base->status,
				   PCC_STS_CMD_COMPLETE)) {
				   PCC_STATUS_CMD_COMPLETE)) {
		msg = generic_comm_base + 1;

		/* Response message msg[1] contains the return value. */
@@ -186,10 +178,10 @@ static void slimpro_i2c_pcc_tx_prepare(struct slimpro_i2c_dev *ctx, u32 *msg)
		   cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));

	WRITE_ONCE(generic_comm_base->command,
		   cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INT));
		   cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));

	status = le16_to_cpu(READ_ONCE(generic_comm_base->status));
	status &= ~PCC_STS_CMD_COMPLETE;
	status &= ~PCC_STATUS_CMD_COMPLETE;
	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status));

	/* Copy the message to the PCC comm space */
+122 −42
Original line number Diff line number Diff line
@@ -31,10 +31,6 @@

#include "kunpeng_hccs.h"

/* PCC defines */
#define HCCS_PCC_SIGNATURE_MASK		0x50434300
#define HCCS_PCC_STATUS_CMD_COMPLETE	BIT(0)

/*
 * Arbitrary retries in case the remote processor is slow to respond
 * to PCC commands
@@ -89,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,
@@ -112,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;
@@ -133,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");
@@ -149,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;
@@ -174,7 +189,7 @@ static int hccs_register_pcc_channel(struct hccs_dev *hdev)
	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 =
@@ -187,7 +202,7 @@ static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev)
	 * deadline_us(timeout_us) until PCC command complete bit is set(cond)
	 */
	ret = readw_poll_timeout(&comm_base->status, status,
				 status & HCCS_PCC_STATUS_CMD_COMPLETE,
				 status & PCC_STATUS_CMD_COMPLETE,
				 HCCS_POLL_STATUS_TIME_INTERVAL_US,
				 cl_info->deadline_us);
	if (unlikely(ret))
@@ -196,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 = HCCS_PCC_SIGNATURE_MASK | 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);
@@ -229,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",
@@ -244,6 +302,9 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
	}

end:
	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;
}
@@ -531,7 +592,6 @@ static int hccs_get_all_port_info_on_die(struct hccs_dev *hdev,

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;
@@ -1101,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;
@@ -1119,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;
@@ -1129,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;
		}
@@ -1151,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;
@@ -1182,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;
		}
	}
@@ -1216,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)
@@ -1244,25 +1309,40 @@ static int hccs_probe(struct platform_device *pdev)
	return rc;
}

static int hccs_remove(struct platform_device *pdev)
static void hccs_remove(struct platform_device *pdev)
{
	struct hccs_dev *hdev = platform_get_drvdata(pdev);

	hccs_remove_topo_dirs(hdev);
	hccs_unregister_pcc_channel(hdev);

	return 0;
}

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);

static struct platform_driver hccs_driver = {
	.probe = hccs_probe,
	.remove = hccs_remove,
	.remove_new = hccs_remove,
	.driver = {
		.name = "kunpeng_hccs",
		.acpi_match_table = hccs_acpi_match,
+15 −0
Original line number Diff line number Diff line
@@ -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