1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * AMD MP2 1.1 communication interfaces
4 *
5 * Copyright (c) 2022, Advanced Micro Devices, Inc.
6 * All Rights Reserved.
7 *
8 * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
9 */
10 #include <linux/io-64-nonatomic-lo-hi.h>
11 #include <linux/iopoll.h>
12
13 #include "amd_sfh_interface.h"
14
amd_sfh_wait_response(struct amd_mp2_dev * mp2,u8 sid,u32 cmd_id)15 static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
16 {
17 struct sfh_cmd_response cmd_resp;
18
19 /* Get response with status within a max of 1600 ms timeout */
20 if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
21 (cmd_resp.response.response == 0 &&
22 cmd_resp.response.cmd_id == cmd_id && (sid == 0xff ||
23 cmd_resp.response.sensor_id == sid)), 500, 1600000))
24 return cmd_resp.response.response;
25
26 return -1;
27 }
28
amd_start_sensor(struct amd_mp2_dev * privdata,struct amd_mp2_sensor_info info)29 static void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
30 {
31 struct sfh_cmd_base cmd_base;
32
33 cmd_base.ul = 0;
34 cmd_base.cmd.cmd_id = ENABLE_SENSOR;
35 cmd_base.cmd.intr_disable = 0;
36 cmd_base.cmd.sensor_id = info.sensor_idx;
37
38 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
39 }
40
amd_stop_sensor(struct amd_mp2_dev * privdata,u16 sensor_idx)41 static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
42 {
43 struct sfh_cmd_base cmd_base;
44
45 cmd_base.ul = 0;
46 cmd_base.cmd.cmd_id = DISABLE_SENSOR;
47 cmd_base.cmd.intr_disable = 0;
48 cmd_base.cmd.sensor_id = sensor_idx;
49
50 writeq(0x0, privdata->mmio + AMD_C2P_MSG(1));
51 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
52 }
53
amd_stop_all_sensor(struct amd_mp2_dev * privdata)54 static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
55 {
56 struct sfh_cmd_base cmd_base;
57
58 cmd_base.ul = 0;
59 cmd_base.cmd.cmd_id = STOP_ALL_SENSORS;
60 cmd_base.cmd.intr_disable = 0;
61
62 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
63 }
64
65 static struct amd_mp2_ops amd_sfh_ops = {
66 .start = amd_start_sensor,
67 .stop = amd_stop_sensor,
68 .stop_all = amd_stop_all_sensor,
69 .response = amd_sfh_wait_response,
70 };
71
sfh_interface_init(struct amd_mp2_dev * mp2)72 void sfh_interface_init(struct amd_mp2_dev *mp2)
73 {
74 mp2->mp2_ops = &amd_sfh_ops;
75 }
76