^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * System Control and Power Interface (SCPI) Message Protocol driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2014 ARM Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * under the terms and conditions of the GNU General Public License,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * version 2, as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This program is distributed in the hope it will be useful, but WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * You should have received a copy of the GNU General Public License along with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * this program. If not, see <http://www.gnu.org/licenses/>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mailbox_client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <soc/rockchip/scpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <soc/rockchip/rk3368-mailbox.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SCPI_VERSION 0x01000002 /* version: 1.0.0.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CMD_ID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CMD_ID_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CMD_SENDER_ID_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CMD_SENDER_ID_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CMD_DATA_SIZE_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CMD_DATA_SIZE_MASK 0x1ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PACK_SCPI_CMD(cmd, sender, txsz) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ((((cmd) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (((txsz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SCPI_CMD_DEFAULT_TIMEOUT_MS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MAX_DVFS_DOMAINS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MAX_DVFS_OPPS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DVFS_LATENCY(hdr) ((hdr) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DVFS_OPP_COUNT(hdr) (((hdr) >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int max_chan_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static DECLARE_BITMAP(bm_mbox_chans, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static DEFINE_MUTEX(scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) enum scpi_error_codes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) SCPI_SUCCESS = 0, /* Success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) SCPI_ERR_ALIGN = 2, /* Invalid alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) SCPI_ERR_SIZE = 3, /* Invalid size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) SCPI_ERR_RANGE = 6, /* Value out of range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) SCPI_ERR_DEVICE = 11, /* Device error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) SCPI_ERR_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) enum scpi_client_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) SCPI_CL_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) SCPI_CL_CLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SCPI_CL_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) SCPI_CL_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SCPI_CL_THERMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) SCPI_CL_SYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) SCPI_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) enum scpi_ddr_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) SCPI_DDR_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) SCPI_DDR_SET_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) SCPI_DDR_ROUND_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) SCPI_DDR_AUTO_SELF_REFRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) SCPI_DDR_BANDWIDTH_GET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) SCPI_DDR_GET_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) SCPI_DDR_SEND_TIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) SCPI_DDR_DCLK_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum scpi_sys_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) SCPI_SYS_GET_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) SCPI_SYS_REFRESH_MCU_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) SCPI_SYS_SET_MCU_STATE_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) SCPI_SYS_SET_MCU_STATE_RESUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) SCPI_SYS_SET_JTAGMUX_ON_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) enum scpi_std_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) SCPI_CMD_INVALID = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) SCPI_CMD_SCPI_READY = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) SCPI_CMD_SCPI_CAPABILITIES = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) SCPI_CMD_EVENT = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) SCPI_CMD_SYS_PWR_STATE = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) SCPI_CMD_L2_READY = 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) SCPI_CMD_SET_AP_TIMER = 0x0a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) SCPI_CMD_CANCEL_AP_TIME = 0x0b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) SCPI_CMD_GET_DVFS_INFO = 0x0d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) SCPI_CMD_SET_DVFS = 0x0e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) SCPI_CMD_GET_DVFS = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) SCPI_CMD_GET_DVFS_STAT = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) SCPI_CMD_SET_RTC = 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) SCPI_CMD_GET_RTC = 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) SCPI_CMD_SET_CLOCK_INDEX = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) SCPI_CMD_SET_CLOCK_VALUE = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) SCPI_CMD_GET_CLOCK_VALUE = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) SCPI_CMD_PSU_CAPABILITIES = 0x17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) SCPI_CMD_SET_PSU = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SCPI_CMD_GET_PSU = 0x19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) SCPI_CMD_SENSOR_INFO = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) SCPI_CMD_SENSOR_VALUE = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) SCPI_CMD_COUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) enum scpi_thermal_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) SCPI_THERMAL_GET_TSADC_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) SCPI_THERMAL_SET_TSADC_CYCLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SCPI_THERMAL_COUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int high_priority_cmds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) SCPI_CMD_GET_CSS_PWR_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) SCPI_CMD_CFG_PWR_STATE_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) SCPI_CMD_GET_PWR_STATE_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) SCPI_CMD_SET_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SCPI_CMD_GET_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) SCPI_CMD_SET_RTC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) SCPI_CMD_GET_RTC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) SCPI_CMD_SET_CLOCK_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SCPI_CMD_SET_CLOCK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) SCPI_CMD_GET_CLOCK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SCPI_CMD_SET_PSU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) SCPI_CMD_GET_PSU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) SCPI_CMD_SENSOR_CFG_PERIODIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) SCPI_CMD_SENSOR_CFG_BOUNDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct scpi_data_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int client_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct rk3368_mbox_msg *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct completion complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int timeout_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct scpi_mcu_ver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 scpi_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) char mcu_ver[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static struct device *the_scpi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int scpi_linux_errmap[SCPI_ERR_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 0, -EINVAL, -ENOEXEC, -EMSGSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) -EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) -ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline int scpi_to_linux_errno(int errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return scpi_linux_errmap[errno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static bool __maybe_unused high_priority_chan_supported(int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (cmd == high_priority_cmds[idx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int scpi_alloc_mbox_chan(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mutex_lock(&scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) index = find_first_zero_bit(bm_mbox_chans, max_chan_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (index >= max_chan_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pr_err("alloc mailbox channel failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mutex_unlock(&scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) set_bit(index, bm_mbox_chans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mutex_unlock(&scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static void scpi_free_mbox_chan(int chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int index = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mutex_lock(&scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (index < max_chan_num && index >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) clear_bit(index, bm_mbox_chans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mutex_unlock(&scpi_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void scpi_rx_callback(struct mbox_client *cl, void *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct rk3368_mbox_msg *data = (struct rk3368_mbox_msg *)msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct scpi_data_buf *scpi_buf = data->cl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) complete(&scpi_buf->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct mbox_chan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct mbox_client cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct rk3368_mbox_msg *data = scpi_buf->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!the_scpi_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) pr_err("Scpi initializes unsuccessfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) cl.dev = the_scpi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cl.rx_callback = scpi_rx_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cl.tx_done = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) cl.tx_prepare = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) cl.tx_block = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) cl.knows_txdone = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) chan = mbox_request_channel(&cl, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (IS_ERR(chan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) scpi_free_mbox_chan(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return PTR_ERR(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) init_completion(&scpi_buf->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (mbox_send_message(chan, (void *)data) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) status = SCPI_ERR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto free_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) status = SCPI_ERR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto free_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) status = *(u32 *)(data->rx_buf); /* read first word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) free_channel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mbox_free_channel(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) scpi_free_mbox_chan(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return scpi_to_linux_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) _cmd, _tx_buf, _rx_buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct rk3368_mbox_msg *pdata = &mbox_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pdata->cmd = _cmd; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pdata->tx_buf = &_tx_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pdata->tx_size = sizeof(_tx_buf); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pdata->rx_buf = &_rx_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pdata->rx_size = sizeof(_rx_buf); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) scpi_buf.client_id = _client_id; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) scpi_buf.data = pdata; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) _cmd, _tx_buf, _tx_size, _rx_buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct rk3368_mbox_msg *pdata = &mbox_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pdata->cmd = _cmd; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pdata->tx_buf = _tx_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) pdata->tx_size = _tx_size; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pdata->rx_buf = &_rx_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pdata->rx_size = sizeof(_rx_buf); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) scpi_buf.client_id = _client_id; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) scpi_buf.data = pdata; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct rk3368_mbox_msg *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!scpi_buf || !scpi_buf->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) index = scpi_alloc_mbox_chan();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) data = scpi_buf->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) data->tx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) data->cl_data = scpi_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return send_scpi_cmd(scpi_buf, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned long scpi_clk_get_val(u16 clk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (scpi_execute_cmd(&sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return buf.clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) EXPORT_SYMBOL_GPL(scpi_clk_get_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int scpi_clk_set_val(u16 clk_id, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) u16 clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) buf.clk_rate = (u32)rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) buf.clk_id = clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) EXPORT_SYMBOL_GPL(scpi_clk_set_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u32 header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct scpi_opp_entry opp[MAX_DVFS_OPPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct scpi_opp *opps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) size_t opps_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) int count, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (domain >= MAX_DVFS_DOMAINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (scpi_opps[domain]) /* data already populated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return scpi_opps[domain];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SCPI_CMD_GET_DVFS_INFO, domain, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) opps = kmalloc(sizeof(*opps), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!opps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) count = DVFS_OPP_COUNT(buf.header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) opps_sz = count * sizeof(*(opps->opp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) opps->count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) opps->latency = DVFS_LATENCY(buf.header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) opps->opp = kmalloc(opps_sz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!opps->opp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) kfree(opps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) memcpy(opps->opp, &buf.opp[0], opps_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) scpi_opps[domain] = opps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return opps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int scpi_dvfs_get_idx(u8 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u8 dvfs_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (domain >= MAX_DVFS_DOMAINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) SCPI_CMD_GET_DVFS, domain, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = buf.dvfs_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int scpi_dvfs_set_idx(u8 domain, u8 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u8 dvfs_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 dvfs_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) buf.dvfs_idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) buf.dvfs_domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (domain >= MAX_DVFS_DOMAINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) SCPI_CMD_SET_DVFS, buf, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int scpi_get_sensor(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u16 sensors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) } cap_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u16 sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u8 class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u8 trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) char name[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) } info_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u16 sensor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* This should be handled by a generic macro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct rk3368_mbox_msg *pdata = &mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pdata->tx_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pdata->rx_buf = &cap_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pdata->rx_size = sizeof(cap_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) sdata.client_id = SCPI_CL_THERMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sdata.data = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (sensor_id = 0; sensor_id < cap_buf.sensors; sensor_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) SCPI_CMD_SENSOR_INFO, sensor_id, info_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!strcmp(name, info_buf.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = sensor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) EXPORT_SYMBOL_GPL(scpi_get_sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int scpi_get_sensor_value(u16 sensor, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) sensor, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) *val = buf.val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct __packed {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct scpi_mcu_ver version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) memset(&buf, 0, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) old, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) pr_err("get scpi version from MCU failed, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) memcpy(ver, &(buf.version), sizeof(*ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int scpi_sys_set_mcu_state_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) tx_buf.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int scpi_sys_set_mcu_state_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) tx_buf.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int scpi_sys_set_jtagmux_on_off(u32 en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u32 enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) tx_buf.enable = en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) SCPI_SYS_SET_JTAGMUX_ON_OFF, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) pr_err("set jtagmux on-off failed, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ret = rx_buf.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) EXPORT_SYMBOL_GPL(scpi_sys_set_jtagmux_on_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int scpi_ddr_dclk_mode(u32 dclk_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) u32 dclk_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) tx_buf.dclk_mode = (u32)dclk_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) SCPI_DDR_DCLK_MODE, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) EXPORT_SYMBOL_GPL(scpi_ddr_dclk_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) u32 dram_speed_bin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) u32 lcdc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) u32 addr_mcu_el3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) tx_buf.dram_speed_bin = (u32)dram_speed_bin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) tx_buf.freq = (u32)freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) tx_buf.lcdc_type = (u32)lcdc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) tx_buf.addr_mcu_el3 = addr_mcu_el3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) SCPI_DDR_INIT, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) EXPORT_SYMBOL_GPL(scpi_ddr_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) u32 lcdc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) tx_buf.clk_rate = (u32)rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) tx_buf.lcdc_type = (u32)lcdc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if ((!ret) && (!rx_buf.status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = rx_buf.freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int scpi_ddr_send_timing(u32 *p, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) SCPI_SETUP_DBUF_BY_SIZE(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) SCPI_DDR_SEND_TIMING, p, size, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) EXPORT_SYMBOL_GPL(scpi_ddr_send_timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int scpi_ddr_round_rate(u32 m_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u32 round_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) tx_buf.clk_rate = (u32)m_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (scpi_execute_cmd(&sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return rx_buf.round_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int scpi_ddr_set_auto_self_refresh(u32 en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) u32 enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) tx_buf.enable = (u32)en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) SCPI_DDR_AUTO_SELF_REFRESH, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int scpi_ddr_get_clk_rate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) tx_buf.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (scpi_execute_cmd(&sdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return rx_buf.clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int scpi_thermal_get_temperature(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u32 tsadc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) tx_buf.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ret = scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pr_err("get temperature from MCU failed, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return rx_buf.tsadc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int scpi_thermal_set_clk_cycle(u32 cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct scpi_data_buf sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct rk3368_mbox_msg mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct __packed1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) u32 clk_cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) } tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct __packed2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) } rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) tx_buf.clk_cycle = cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return scpi_execute_cmd(&sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static struct of_device_id mobx_scpi_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) { .compatible = "rockchip,rk3368-scpi-legacy"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int mobx_scpi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) int retry = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct scpi_mcu_ver mcu_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int check_version = 1; /*0: not check version, 1: check version*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) the_scpi_device = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /* try to get mboxes chan nums from DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) max_chan_num = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* try to check up with SCPI version from MCU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) while ((retry--) && (check_version != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) memset(&mcu_ver, 0, sizeof(mcu_ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if ((retry <= 0) && (check_version != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) SCPI_VERSION, mcu_ver.scpi_ver, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) SCPI_VERSION, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (check_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) the_scpi_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static struct platform_driver mbox_scpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) .probe = mobx_scpi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .name = "mbox-scpi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .of_match_table = of_match_ptr(mobx_scpi_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int __init rockchip_mbox_scpi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return platform_driver_register(&mbox_scpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) subsys_initcall(rockchip_mbox_scpi_init);