1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2023, Intel Corporation. 4 * Intel Visual Sensing Controller Interface Linux driver 5 */ 6 7 #include <linux/align.h> 8 #include <linux/cache.h> 9 #include <linux/cleanup.h> 10 #include <linux/iopoll.h> 11 #include <linux/list.h> 12 #include <linux/mei.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/overflow.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/timekeeping.h> 19 #include <linux/types.h> 20 21 #include <asm-generic/bug.h> 22 #include <asm-generic/unaligned.h> 23 24 #include "mei_dev.h" 25 #include "vsc-tp.h" 26 27 #define MEI_VSC_DRV_NAME "intel_vsc" 28 29 #define MEI_VSC_MAX_MSG_SIZE 512 30 31 #define MEI_VSC_POLL_DELAY_US (50 * USEC_PER_MSEC) 32 #define MEI_VSC_POLL_TIMEOUT_US (200 * USEC_PER_MSEC) 33 34 #define mei_dev_to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw)) 35 36 struct mei_vsc_host_timestamp { 37 u64 realtime; 38 u64 boottime; 39 }; 40 41 struct mei_vsc_hw { 42 struct vsc_tp *tp; 43 44 bool fw_ready; 45 bool host_ready; 46 47 atomic_t write_lock_cnt; 48 49 u32 rx_len; 50 u32 rx_hdr; 51 52 /* buffer for tx */ 53 char tx_buf[MEI_VSC_MAX_MSG_SIZE + sizeof(struct mei_msg_hdr)] ____cacheline_aligned; 54 /* buffer for rx */ 55 char rx_buf[MEI_VSC_MAX_MSG_SIZE + sizeof(struct mei_msg_hdr)] ____cacheline_aligned; 56 }; 57 58 static int mei_vsc_read_helper(struct mei_vsc_hw *hw, u8 *buf, 59 u32 max_len) 60 { 61 struct mei_vsc_host_timestamp ts = { 62 .realtime = ktime_to_ns(ktime_get_real()), 63 .boottime = ktime_to_ns(ktime_get_boottime()), 64 }; 65 66 return vsc_tp_xfer(hw->tp, VSC_TP_CMD_READ, &ts, sizeof(ts), 67 buf, max_len); 68 } 69 70 static int mei_vsc_write_helper(struct mei_vsc_hw *hw, u8 *buf, u32 len) 71 { 72 u8 status; 73 74 return vsc_tp_xfer(hw->tp, VSC_TP_CMD_WRITE, buf, len, &status, 75 sizeof(status)); 76 } 77 78 static int mei_vsc_fw_status(struct mei_device *mei_dev, 79 struct mei_fw_status *fw_status) 80 { 81 if (!fw_status) 82 return -EINVAL; 83 84 fw_status->count = 0; 85 86 return 0; 87 } 88 89 static inline enum mei_pg_state mei_vsc_pg_state(struct mei_device *mei_dev) 90 { 91 return MEI_PG_OFF; 92 } 93 94 static void mei_vsc_intr_enable(struct mei_device *mei_dev) 95 { 96 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 97 98 vsc_tp_intr_enable(hw->tp); 99 } 100 101 static void mei_vsc_intr_disable(struct mei_device *mei_dev) 102 { 103 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 104 105 vsc_tp_intr_disable(hw->tp); 106 } 107 108 /* mei framework requires this ops */ 109 static void mei_vsc_intr_clear(struct mei_device *mei_dev) 110 { 111 } 112 113 /* wait for pending irq handler */ 114 static void mei_vsc_synchronize_irq(struct mei_device *mei_dev) 115 { 116 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 117 118 vsc_tp_intr_synchronize(hw->tp); 119 } 120 121 static int mei_vsc_hw_config(struct mei_device *mei_dev) 122 { 123 return 0; 124 } 125 126 static bool mei_vsc_host_is_ready(struct mei_device *mei_dev) 127 { 128 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 129 130 return hw->host_ready; 131 } 132 133 static bool mei_vsc_hw_is_ready(struct mei_device *mei_dev) 134 { 135 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 136 137 return hw->fw_ready; 138 } 139 140 static int mei_vsc_hw_start(struct mei_device *mei_dev) 141 { 142 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 143 int ret, rlen; 144 u8 buf; 145 146 hw->host_ready = true; 147 148 vsc_tp_intr_enable(hw->tp); 149 150 ret = read_poll_timeout(mei_vsc_read_helper, rlen, 151 rlen >= 0, MEI_VSC_POLL_DELAY_US, 152 MEI_VSC_POLL_TIMEOUT_US, true, 153 hw, &buf, sizeof(buf)); 154 if (ret) { 155 dev_err(mei_dev->dev, "wait fw ready failed: %d\n", ret); 156 return ret; 157 } 158 159 hw->fw_ready = true; 160 161 return 0; 162 } 163 164 static bool mei_vsc_hbuf_is_ready(struct mei_device *mei_dev) 165 { 166 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 167 168 return atomic_read(&hw->write_lock_cnt) == 0; 169 } 170 171 static int mei_vsc_hbuf_empty_slots(struct mei_device *mei_dev) 172 { 173 return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE; 174 } 175 176 static u32 mei_vsc_hbuf_depth(const struct mei_device *mei_dev) 177 { 178 return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE; 179 } 180 181 static int mei_vsc_write(struct mei_device *mei_dev, 182 const void *hdr, size_t hdr_len, 183 const void *data, size_t data_len) 184 { 185 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 186 char *buf = hw->tx_buf; 187 int ret; 188 189 if (WARN_ON(!hdr || !IS_ALIGNED(hdr_len, 4))) 190 return -EINVAL; 191 192 if (!data || data_len > MEI_VSC_MAX_MSG_SIZE) 193 return -EINVAL; 194 195 atomic_inc(&hw->write_lock_cnt); 196 197 memcpy(buf, hdr, hdr_len); 198 memcpy(buf + hdr_len, data, data_len); 199 200 ret = mei_vsc_write_helper(hw, buf, hdr_len + data_len); 201 202 atomic_dec_if_positive(&hw->write_lock_cnt); 203 204 return ret < 0 ? ret : 0; 205 } 206 207 static inline u32 mei_vsc_read(const struct mei_device *mei_dev) 208 { 209 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 210 int ret; 211 212 ret = mei_vsc_read_helper(hw, hw->rx_buf, sizeof(hw->rx_buf)); 213 if (ret < 0 || ret < sizeof(u32)) 214 return 0; 215 hw->rx_len = ret; 216 217 hw->rx_hdr = get_unaligned_le32(hw->rx_buf); 218 219 return hw->rx_hdr; 220 } 221 222 static int mei_vsc_count_full_read_slots(struct mei_device *mei_dev) 223 { 224 return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE; 225 } 226 227 static int mei_vsc_read_slots(struct mei_device *mei_dev, unsigned char *buf, 228 unsigned long len) 229 { 230 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 231 struct mei_msg_hdr *hdr; 232 233 hdr = (struct mei_msg_hdr *)&hw->rx_hdr; 234 if (len != hdr->length || hdr->length + sizeof(*hdr) != hw->rx_len) 235 return -EINVAL; 236 237 memcpy(buf, hw->rx_buf + sizeof(*hdr), len); 238 239 return 0; 240 } 241 242 static bool mei_vsc_pg_in_transition(struct mei_device *mei_dev) 243 { 244 return mei_dev->pg_event >= MEI_PG_EVENT_WAIT && 245 mei_dev->pg_event <= MEI_PG_EVENT_INTR_WAIT; 246 } 247 248 static bool mei_vsc_pg_is_enabled(struct mei_device *mei_dev) 249 { 250 return false; 251 } 252 253 static int mei_vsc_hw_reset(struct mei_device *mei_dev, bool intr_enable) 254 { 255 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 256 257 vsc_tp_reset(hw->tp); 258 259 vsc_tp_intr_disable(hw->tp); 260 261 return vsc_tp_init(hw->tp, mei_dev->dev); 262 } 263 264 static const struct mei_hw_ops mei_vsc_hw_ops = { 265 .fw_status = mei_vsc_fw_status, 266 .pg_state = mei_vsc_pg_state, 267 268 .host_is_ready = mei_vsc_host_is_ready, 269 .hw_is_ready = mei_vsc_hw_is_ready, 270 .hw_reset = mei_vsc_hw_reset, 271 .hw_config = mei_vsc_hw_config, 272 .hw_start = mei_vsc_hw_start, 273 274 .pg_in_transition = mei_vsc_pg_in_transition, 275 .pg_is_enabled = mei_vsc_pg_is_enabled, 276 277 .intr_clear = mei_vsc_intr_clear, 278 .intr_enable = mei_vsc_intr_enable, 279 .intr_disable = mei_vsc_intr_disable, 280 .synchronize_irq = mei_vsc_synchronize_irq, 281 282 .hbuf_free_slots = mei_vsc_hbuf_empty_slots, 283 .hbuf_is_ready = mei_vsc_hbuf_is_ready, 284 .hbuf_depth = mei_vsc_hbuf_depth, 285 .write = mei_vsc_write, 286 287 .rdbuf_full_slots = mei_vsc_count_full_read_slots, 288 .read_hdr = mei_vsc_read, 289 .read = mei_vsc_read_slots, 290 }; 291 292 static void mei_vsc_event_cb(void *context) 293 { 294 struct mei_device *mei_dev = context; 295 struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev); 296 struct list_head cmpl_list; 297 s32 slots; 298 int ret; 299 300 if (mei_dev->dev_state == MEI_DEV_RESETTING || 301 mei_dev->dev_state == MEI_DEV_INITIALIZING) 302 return; 303 304 INIT_LIST_HEAD(&cmpl_list); 305 306 guard(mutex)(&mei_dev->device_lock); 307 308 while (vsc_tp_need_read(hw->tp)) { 309 /* check slots available for reading */ 310 slots = mei_count_full_read_slots(mei_dev); 311 312 ret = mei_irq_read_handler(mei_dev, &cmpl_list, &slots); 313 if (ret) { 314 if (ret != -ENODATA) { 315 if (mei_dev->dev_state != MEI_DEV_RESETTING && 316 mei_dev->dev_state != MEI_DEV_POWER_DOWN) 317 schedule_work(&mei_dev->reset_work); 318 } 319 320 return; 321 } 322 } 323 324 mei_dev->hbuf_is_ready = mei_hbuf_is_ready(mei_dev); 325 ret = mei_irq_write_handler(mei_dev, &cmpl_list); 326 if (ret) 327 dev_err(mei_dev->dev, "dispatch write request failed: %d\n", ret); 328 329 mei_dev->hbuf_is_ready = mei_hbuf_is_ready(mei_dev); 330 mei_irq_compl_handler(mei_dev, &cmpl_list); 331 } 332 333 static int mei_vsc_probe(struct platform_device *pdev) 334 { 335 struct device *dev = &pdev->dev; 336 struct mei_device *mei_dev; 337 struct mei_vsc_hw *hw; 338 struct vsc_tp *tp; 339 int ret; 340 341 tp = *(struct vsc_tp **)dev_get_platdata(dev); 342 if (!tp) 343 return dev_err_probe(dev, -ENODEV, "no platform data\n"); 344 345 mei_dev = devm_kzalloc(dev, size_add(sizeof(*mei_dev), sizeof(*hw)), 346 GFP_KERNEL); 347 if (!mei_dev) 348 return -ENOMEM; 349 350 mei_device_init(mei_dev, dev, false, &mei_vsc_hw_ops); 351 mei_dev->fw_f_fw_ver_supported = 0; 352 mei_dev->kind = "ivsc"; 353 354 hw = mei_dev_to_vsc_hw(mei_dev); 355 atomic_set(&hw->write_lock_cnt, 0); 356 hw->tp = tp; 357 358 platform_set_drvdata(pdev, mei_dev); 359 360 vsc_tp_register_event_cb(tp, mei_vsc_event_cb, mei_dev); 361 362 ret = mei_start(mei_dev); 363 if (ret) { 364 dev_err_probe(dev, ret, "init hw failed\n"); 365 goto err_cancel; 366 } 367 368 ret = mei_register(mei_dev, dev); 369 if (ret) 370 goto err_stop; 371 372 pm_runtime_enable(mei_dev->dev); 373 374 return 0; 375 376 err_stop: 377 mei_stop(mei_dev); 378 379 err_cancel: 380 mei_cancel_work(mei_dev); 381 382 mei_disable_interrupts(mei_dev); 383 384 return ret; 385 } 386 387 static void mei_vsc_remove(struct platform_device *pdev) 388 { 389 struct mei_device *mei_dev = platform_get_drvdata(pdev); 390 391 pm_runtime_disable(mei_dev->dev); 392 393 mei_stop(mei_dev); 394 395 mei_disable_interrupts(mei_dev); 396 397 mei_deregister(mei_dev); 398 } 399 400 static int mei_vsc_suspend(struct device *dev) 401 { 402 struct mei_device *mei_dev = dev_get_drvdata(dev); 403 404 mei_stop(mei_dev); 405 406 return 0; 407 } 408 409 static int mei_vsc_resume(struct device *dev) 410 { 411 struct mei_device *mei_dev = dev_get_drvdata(dev); 412 int ret; 413 414 ret = mei_restart(mei_dev); 415 if (ret) 416 return ret; 417 418 /* start timer if stopped in suspend */ 419 schedule_delayed_work(&mei_dev->timer_work, HZ); 420 421 return 0; 422 } 423 424 static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume); 425 426 static const struct platform_device_id mei_vsc_id_table[] = { 427 { MEI_VSC_DRV_NAME }, 428 { /* sentinel */ } 429 }; 430 MODULE_DEVICE_TABLE(platform, mei_vsc_id_table); 431 432 static struct platform_driver mei_vsc_drv = { 433 .probe = mei_vsc_probe, 434 .remove_new = mei_vsc_remove, 435 .id_table = mei_vsc_id_table, 436 .driver = { 437 .name = MEI_VSC_DRV_NAME, 438 .pm = &mei_vsc_pm_ops, 439 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 440 }, 441 }; 442 module_platform_driver(mei_vsc_drv); 443 444 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>"); 445 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>"); 446 MODULE_DESCRIPTION("Intel Visual Sensing Controller Interface"); 447 MODULE_LICENSE("GPL"); 448 MODULE_IMPORT_NS(VSC_TP); 449