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 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 10000 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, 10000000)) 24 return cmd_resp.response.response; 25 26 return -1; 27 } 28 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.sub_cmd_value = 1; 37 cmd_base.cmd.sensor_id = info.sensor_idx; 38 39 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); 40 } 41 42 static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx) 43 { 44 struct sfh_cmd_base cmd_base; 45 46 cmd_base.ul = 0; 47 cmd_base.cmd.cmd_id = DISABLE_SENSOR; 48 cmd_base.cmd.intr_disable = 0; 49 cmd_base.cmd.sub_cmd_value = 1; 50 cmd_base.cmd.sensor_id = sensor_idx; 51 52 writeq(0x0, privdata->mmio + AMD_C2P_MSG(1)); 53 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); 54 } 55 56 static void amd_stop_all_sensor(struct amd_mp2_dev *privdata) 57 { 58 struct sfh_cmd_base cmd_base; 59 60 cmd_base.ul = 0; 61 cmd_base.cmd.cmd_id = DISABLE_SENSOR; 62 cmd_base.cmd.intr_disable = 0; 63 /* 0xf indicates all sensors */ 64 cmd_base.cmd.sensor_id = 0xf; 65 66 writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); 67 } 68 69 static struct amd_mp2_ops amd_sfh_ops = { 70 .start = amd_start_sensor, 71 .stop = amd_stop_sensor, 72 .stop_all = amd_stop_all_sensor, 73 .response = amd_sfh_wait_response, 74 }; 75 76 void sfh_interface_init(struct amd_mp2_dev *mp2) 77 { 78 mp2->mp2_ops = &amd_sfh_ops; 79 } 80