diff mbox series

[v3,8/9] i2c: designware: Add doorbell support for Skyrim

Message ID 20230303165050.2918-9-mario.limonciello@amd.com
State New
Headers show
Series Export platform features from ccp driver | expand

Commit Message

Mario Limonciello March 3, 2023, 4:50 p.m. UTC
Skyrim doesn't use the platform feature mailbox for communication
for I2C arbitration, it relies upon ringing a doorbell.

Link: https://lore.kernel.org/linux-i2c/20220916131854.687371-3-jsd@semihalf.com/
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
v2->v3:
 * Use CPU ID rather than ACPI ID, this will be pushed to a later patch
v1->v2:
 * New patch

doorbell; get status field
---
 drivers/i2c/busses/i2c-designware-amdpsp.c | 28 ++++++++++++++--------
 1 file changed, 18 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c
index 105584abcf8f..2c671973010d 100644
--- a/drivers/i2c/busses/i2c-designware-amdpsp.c
+++ b/drivers/i2c/busses/i2c-designware-amdpsp.c
@@ -73,34 +73,43 @@  static int psp_send_check_i2c_req(struct psp_i2c_req *req)
 	return check_i2c_req_sts(req);
 }
 
-static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type)
+static int psp_send_i2c_req_amdi0019(enum psp_i2c_req_type i2c_req_type)
 {
 	struct psp_i2c_req *req;
-	unsigned long start;
 	int status, ret;
 
 	/* Allocate command-response buffer */
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
 	if (!req)
 		return -ENOMEM;
-
 	req->hdr.payload_size = sizeof(*req);
 	req->type = i2c_req_type;
-
-	start = jiffies;
 	ret = read_poll_timeout(psp_send_check_i2c_req, status,
 				(status != -EBUSY),
 				PSP_I2C_REQ_RETRY_DELAY_US,
 				PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US,
 				0, req);
-	if (ret) {
+	kfree(req);
+
+	if (ret)
 		dev_err(psp_i2c_dev, "Timed out waiting for PSP to %s I2C bus\n",
 			(i2c_req_type == PSP_I2C_REQ_ACQUIRE) ?
 			"release" : "acquire");
-		goto cleanup;
-	}
 
-	ret = status;
+	return ret ? ret : status;
+}
+
+static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type)
+{
+	unsigned long start = jiffies;
+	int ret;
+
+	/* Use doorbell for Skyrim and mailbox for Cezanne */
+	if (boot_cpu_data.x86 == 25 && boot_cpu_data.x86_model == 80)
+		ret = psp_send_i2c_req_amdi0019(i2c_req_type);
+	else
+		ret = psp_ring_platform_doorbell(i2c_req_type);
+
 	if (ret) {
 		dev_err(psp_i2c_dev, "PSP communication error\n");
 		goto cleanup;
@@ -115,7 +124,6 @@  static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type)
 		psp_i2c_mbox_fail = true;
 	}
 
-	kfree(req);
 	return ret;
 }