1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <ddk/debug.h> 8 #include <ddk/platform-defs.h> 9 #include <ddk/protocol/platform-device-lib.h> 10 #include <ddk/protocol/platform/bus.h> 11 #include <ddk/protocol/platform/device.h> 12 #include <ddktl/device.h> 13 #include <ddktl/mmio.h> 14 #include <ddktl/pdev.h> 15 #include <ddktl/protocol/mailbox.h> 16 #include <ddktl/protocol/scpi.h> 17 #include <hw/reg.h> 18 #include <lib/sync/completion.h> 19 #include <threads.h> 20 21 #include <optional> 22 23 #define SCPI_ERROR(fmt, ...) zxlogf(ERROR, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__) 24 #define SCPI_INFO(fmt, ...) zxlogf(INFO, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__) 25 #define VALID_CMD(cmd) (cmd > SCPI_CMD_INVALID && cmd < SCPI_CMD_MAX) 26 27 #define CMD_ID_SHIFT 0 28 #define CMD_ID_MASK 0xff 29 #define CMD_SENDER_ID_SHIFT 8 30 #define CMD_SENDER_ID_MASK 0xff 31 #define CMD_DATA_SIZE_SHIFT 20 32 #define CMD_DATA_SIZE_MASK 0x1ff 33 #define PACK_SCPI_CMD(cmd, sender, txsz) \ 34 ((((cmd)&CMD_ID_MASK) << CMD_ID_SHIFT) | \ 35 (((sender)&CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \ 36 (((txsz)&CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT)) 37 38 namespace scpi { 39 40 class AmlSCPI; 41 using DeviceType = ddk::Device<AmlSCPI, ddk::Unbindable>; 42 43 class AmlSCPI : public DeviceType, 44 public ddk::ScpiProtocol<AmlSCPI, ddk::base_protocol> { 45 public: 46 DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AmlSCPI); 47 AmlSCPI(zx_device_t * parent)48 explicit AmlSCPI(zx_device_t* parent) 49 : DeviceType(parent), pdev_(parent), mailbox_(parent) {} 50 51 static zx_status_t Create(zx_device_t* parent); 52 53 // DDK Hooks. 54 void DdkRelease(); 55 void DdkUnbind(); 56 57 // ZX_PROTOCOL_SCPI protocol. 58 zx_status_t ScpiGetSensor(const char* name, uint32_t* out_sensor_id); 59 zx_status_t ScpiGetSensorValue(uint32_t sensor_id, uint32_t* out_sensor_value); 60 zx_status_t ScpiGetDvfsInfo(uint8_t power_domain, scpi_opp_t* out_opps); 61 zx_status_t ScpiGetDvfsIdx(uint8_t power_domain, uint16_t* out_index); 62 zx_status_t ScpiSetDvfsIdx(uint8_t power_domain, uint16_t index); 63 64 private: 65 zx_status_t GetMailbox(uint32_t cmd, mailbox_type_t* mailbox); 66 zx_status_t ExecuteCommand(void* rx_buf, size_t rx_size, 67 void* tx_buf, size_t tx_size, 68 uint32_t cmd, uint32_t client_id); 69 zx_status_t Bind(); 70 71 enum { 72 SCPI_CL_NONE, 73 SCPI_CL_CLOCKS, 74 SCPI_CL_DVFS, 75 SCPI_CL_POWER, 76 SCPI_CL_THERMAL, 77 SCPI_CL_REMOTE, 78 SCPI_CL_LED_TIMER, 79 SCPI_MAX, 80 }; 81 82 enum { 83 SCPI_CMD_INVALID = 0x00, 84 SCPI_CMD_SCPI_READY = 0x01, 85 SCPI_CMD_SCPI_CAPABILITIES = 0x02, 86 SCPI_CMD_EVENT = 0x03, 87 SCPI_CMD_SET_CSS_PWR_STATE = 0x04, 88 SCPI_CMD_GET_CSS_PWR_STATE = 0x05, 89 SCPI_CMD_CFG_PWR_STATE_STAT = 0x06, 90 SCPI_CMD_GET_PWR_STATE_STAT = 0x07, 91 SCPI_CMD_SYS_PWR_STATE = 0x08, 92 SCPI_CMD_L2_READY = 0x09, 93 SCPI_CMD_SET_AP_TIMER = 0x0a, 94 SCPI_CMD_CANCEL_AP_TIME = 0x0b, 95 SCPI_CMD_DVFS_CAPABILITIES = 0x0c, 96 SCPI_CMD_GET_DVFS_INFO = 0x0d, 97 SCPI_CMD_SET_DVFS = 0x0e, 98 SCPI_CMD_GET_DVFS = 0x0f, 99 SCPI_CMD_GET_DVFS_STAT = 0x10, 100 SCPI_CMD_SET_RTC = 0x11, 101 SCPI_CMD_GET_RTC = 0x12, 102 SCPI_CMD_CLOCK_CAPABILITIES = 0x13, 103 SCPI_CMD_SET_CLOCK_INDEX = 0x14, 104 SCPI_CMD_SET_CLOCK_VALUE = 0x15, 105 SCPI_CMD_GET_CLOCK_VALUE = 0x16, 106 SCPI_CMD_PSU_CAPABILITIES = 0x17, 107 SCPI_CMD_SET_PSU = 0x18, 108 SCPI_CMD_GET_PSU = 0x19, 109 SCPI_CMD_SENSOR_CAPABILITIES = 0x1a, 110 SCPI_CMD_SENSOR_INFO = 0x1b, 111 SCPI_CMD_SENSOR_VALUE = 0x1c, 112 SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d, 113 SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e, 114 SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f, 115 SCPI_CMD_SET_USR_DATA = 0x20, 116 SCPI_CMD_MAX = 0x21, 117 }; 118 119 static constexpr uint32_t aml_high_priority_cmds[] = { 120 SCPI_CMD_GET_DVFS, 121 SCPI_CMD_SET_DVFS, 122 SCPI_CMD_SET_CLOCK_VALUE, 123 }; 124 125 static constexpr uint32_t aml_low_priority_cmds[] = { 126 SCPI_CMD_GET_DVFS_INFO, 127 SCPI_CMD_SENSOR_CAPABILITIES, 128 SCPI_CMD_SENSOR_INFO, 129 SCPI_CMD_SENSOR_VALUE, 130 }; 131 132 static constexpr uint32_t aml_secure_cmds[] = { 133 SCPI_CMD_SET_CSS_PWR_STATE, 134 SCPI_CMD_SYS_PWR_STATE, 135 }; 136 137 ddk::PDev pdev_; 138 ddk::MailboxProtocolClient mailbox_; 139 mtx_t lock_; 140 scpi_opp_t* scpi_opp[MAX_DVFS_DOMAINS]; 141 }; 142 143 } // namespace scpi 144