0001
0002
0003
0004
0005
0006
0007 #include <linux/types.h>
0008 #include <linux/io.h>
0009 #include <linux/delay.h>
0010 #include <linux/pm_runtime.h>
0011
0012 #include "ipa.h"
0013 #include "ipa_uc.h"
0014 #include "ipa_power.h"
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #define IPA_SEND_DELAY 100
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 struct ipa_uc_mem_area {
0069 u8 command;
0070 u8 reserved0[3];
0071 __le32 command_param;
0072 __le32 command_param_hi;
0073 u8 response;
0074 u8 reserved1[3];
0075 __le32 response_param;
0076 u8 event;
0077 u8 reserved2[3];
0078
0079 __le32 event_param;
0080 __le32 first_error_address;
0081 u8 hw_state;
0082 u8 warning_counter;
0083 __le16 reserved3;
0084 __le16 interface_version;
0085 __le16 reserved4;
0086 };
0087
0088
0089 enum ipa_uc_command {
0090 IPA_UC_COMMAND_NO_OP = 0x0,
0091 IPA_UC_COMMAND_UPDATE_FLAGS = 0x1,
0092 IPA_UC_COMMAND_DEBUG_RUN_TEST = 0x2,
0093 IPA_UC_COMMAND_DEBUG_GET_INFO = 0x3,
0094 IPA_UC_COMMAND_ERR_FATAL = 0x4,
0095 IPA_UC_COMMAND_CLK_GATE = 0x5,
0096 IPA_UC_COMMAND_CLK_UNGATE = 0x6,
0097 IPA_UC_COMMAND_MEMCPY = 0x7,
0098 IPA_UC_COMMAND_RESET_PIPE = 0x8,
0099 IPA_UC_COMMAND_REG_WRITE = 0x9,
0100 IPA_UC_COMMAND_GSI_CH_EMPTY = 0xa,
0101 };
0102
0103
0104 enum ipa_uc_response {
0105 IPA_UC_RESPONSE_NO_OP = 0x0,
0106 IPA_UC_RESPONSE_INIT_COMPLETED = 0x1,
0107 IPA_UC_RESPONSE_CMD_COMPLETED = 0x2,
0108 IPA_UC_RESPONSE_DEBUG_GET_INFO = 0x3,
0109 };
0110
0111
0112 enum ipa_uc_event {
0113 IPA_UC_EVENT_NO_OP = 0x0,
0114 IPA_UC_EVENT_ERROR = 0x1,
0115 IPA_UC_EVENT_LOG_INFO = 0x2,
0116 };
0117
0118 static struct ipa_uc_mem_area *ipa_uc_shared(struct ipa *ipa)
0119 {
0120 const struct ipa_mem *mem = ipa_mem_find(ipa, IPA_MEM_UC_SHARED);
0121 u32 offset = ipa->mem_offset + mem->offset;
0122
0123 return ipa->mem_virt + offset;
0124 }
0125
0126
0127 static void ipa_uc_event_handler(struct ipa *ipa, enum ipa_irq_id irq_id)
0128 {
0129 struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
0130 struct device *dev = &ipa->pdev->dev;
0131
0132 if (shared->event == IPA_UC_EVENT_ERROR)
0133 dev_err(dev, "microcontroller error event\n");
0134 else if (shared->event != IPA_UC_EVENT_LOG_INFO)
0135 dev_err(dev, "unsupported microcontroller event %u\n",
0136 shared->event);
0137
0138 }
0139
0140
0141 static void ipa_uc_response_hdlr(struct ipa *ipa, enum ipa_irq_id irq_id)
0142 {
0143 struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
0144 struct device *dev = &ipa->pdev->dev;
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 switch (shared->response) {
0155 case IPA_UC_RESPONSE_INIT_COMPLETED:
0156 if (ipa->uc_powered) {
0157 ipa->uc_loaded = true;
0158 ipa_power_retention(ipa, true);
0159 pm_runtime_mark_last_busy(dev);
0160 (void)pm_runtime_put_autosuspend(dev);
0161 ipa->uc_powered = false;
0162 } else {
0163 dev_warn(dev, "unexpected init_completed response\n");
0164 }
0165 break;
0166 default:
0167 dev_warn(dev, "unsupported microcontroller response %u\n",
0168 shared->response);
0169 break;
0170 }
0171 }
0172
0173
0174 void ipa_uc_config(struct ipa *ipa)
0175 {
0176 ipa->uc_powered = false;
0177 ipa->uc_loaded = false;
0178 ipa_interrupt_add(ipa->interrupt, IPA_IRQ_UC_0, ipa_uc_event_handler);
0179 ipa_interrupt_add(ipa->interrupt, IPA_IRQ_UC_1, ipa_uc_response_hdlr);
0180 }
0181
0182
0183 void ipa_uc_deconfig(struct ipa *ipa)
0184 {
0185 struct device *dev = &ipa->pdev->dev;
0186
0187 ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_1);
0188 ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_0);
0189 if (ipa->uc_loaded)
0190 ipa_power_retention(ipa, false);
0191
0192 if (!ipa->uc_powered)
0193 return;
0194
0195 pm_runtime_mark_last_busy(dev);
0196 (void)pm_runtime_put_autosuspend(dev);
0197 }
0198
0199
0200 void ipa_uc_power(struct ipa *ipa)
0201 {
0202 static bool already;
0203 struct device *dev;
0204 int ret;
0205
0206 if (already)
0207 return;
0208 already = true;
0209
0210
0211 dev = &ipa->pdev->dev;
0212 ret = pm_runtime_get_sync(dev);
0213 if (ret < 0) {
0214 pm_runtime_put_noidle(dev);
0215 dev_err(dev, "error %d getting proxy power\n", ret);
0216 } else {
0217 ipa->uc_powered = true;
0218 }
0219 }
0220
0221
0222 static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
0223 {
0224 struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
0225 u32 offset;
0226 u32 val;
0227
0228
0229 shared->command = command;
0230 shared->command_param = cpu_to_le32(command_param);
0231 shared->command_param_hi = 0;
0232 shared->response = 0;
0233 shared->response_param = 0;
0234
0235
0236 val = u32_encode_bits(1, UC_INTR_FMASK);
0237 offset = ipa_reg_irq_uc_offset(ipa->version);
0238 iowrite32(val, ipa->reg_virt + offset);
0239 }
0240
0241
0242 void ipa_uc_panic_notifier(struct ipa *ipa)
0243 {
0244 if (!ipa->uc_loaded)
0245 return;
0246
0247 send_uc_command(ipa, IPA_UC_COMMAND_ERR_FATAL, 0);
0248
0249
0250 udelay(IPA_SEND_DELAY);
0251 }