1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/interconnect.h> 8 #include <linux/module.h> 9 #include <linux/pm_domain.h> 10 #include <linux/pm_opp.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/reset.h> 13 14 #include "iris_core.h" 15 #include "iris_ctrls.h" 16 #include "iris_vidc.h" 17 18 static int iris_init_icc(struct iris_core *core) 19 { 20 const struct icc_info *icc_tbl; 21 u32 i = 0; 22 23 icc_tbl = core->iris_platform_data->icc_tbl; 24 25 core->icc_count = core->iris_platform_data->icc_tbl_size; 26 core->icc_tbl = devm_kzalloc(core->dev, 27 sizeof(struct icc_bulk_data) * core->icc_count, 28 GFP_KERNEL); 29 if (!core->icc_tbl) 30 return -ENOMEM; 31 32 for (i = 0; i < core->icc_count; i++) { 33 core->icc_tbl[i].name = icc_tbl[i].name; 34 core->icc_tbl[i].avg_bw = icc_tbl[i].bw_min_kbps; 35 core->icc_tbl[i].peak_bw = 0; 36 } 37 38 return devm_of_icc_bulk_get(core->dev, core->icc_count, core->icc_tbl); 39 } 40 41 static int iris_init_power_domains(struct iris_core *core) 42 { 43 const struct platform_clk_data *clk_tbl; 44 u32 clk_cnt, i; 45 int ret; 46 47 struct dev_pm_domain_attach_data iris_pd_data = { 48 .pd_names = core->iris_platform_data->pmdomain_tbl, 49 .num_pd_names = core->iris_platform_data->pmdomain_tbl_size, 50 .pd_flags = PD_FLAG_NO_DEV_LINK, 51 }; 52 53 struct dev_pm_domain_attach_data iris_opp_pd_data = { 54 .pd_names = core->iris_platform_data->opp_pd_tbl, 55 .num_pd_names = core->iris_platform_data->opp_pd_tbl_size, 56 .pd_flags = PD_FLAG_DEV_LINK_ON | PD_FLAG_REQUIRED_OPP, 57 }; 58 59 ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdomain_tbl); 60 if (ret < 0) 61 return ret; 62 63 ret = devm_pm_domain_attach_list(core->dev, &iris_opp_pd_data, &core->opp_pmdomain_tbl); 64 if (ret < 0) 65 return ret; 66 67 clk_tbl = core->iris_platform_data->clk_tbl; 68 clk_cnt = core->iris_platform_data->clk_tbl_size; 69 70 for (i = 0; i < clk_cnt; i++) { 71 if (clk_tbl[i].clk_type == IRIS_HW_CLK) { 72 ret = devm_pm_opp_set_clkname(core->dev, clk_tbl[i].clk_name); 73 if (ret) 74 return ret; 75 } 76 } 77 78 return devm_pm_opp_of_add_table(core->dev); 79 } 80 81 static int iris_init_clocks(struct iris_core *core) 82 { 83 int ret; 84 85 ret = devm_clk_bulk_get_all(core->dev, &core->clock_tbl); 86 if (ret < 0) 87 return ret; 88 89 core->clk_count = ret; 90 91 return 0; 92 } 93 94 static int iris_init_reset_table(struct iris_core *core, 95 struct reset_control_bulk_data **resets, 96 const char * const *rst_tbl, u32 rst_tbl_size) 97 { 98 u32 i = 0; 99 100 *resets = devm_kzalloc(core->dev, 101 sizeof(struct reset_control_bulk_data) * rst_tbl_size, 102 GFP_KERNEL); 103 if (!*resets) 104 return -ENOMEM; 105 106 for (i = 0; i < rst_tbl_size; i++) 107 (*resets)[i].id = rst_tbl[i]; 108 109 return devm_reset_control_bulk_get_exclusive(core->dev, rst_tbl_size, *resets); 110 } 111 112 static int iris_init_resets(struct iris_core *core) 113 { 114 int ret; 115 116 ret = iris_init_reset_table(core, &core->resets, 117 core->iris_platform_data->clk_rst_tbl, 118 core->iris_platform_data->clk_rst_tbl_size); 119 if (ret) 120 return ret; 121 122 if (!core->iris_platform_data->controller_rst_tbl_size) 123 return 0; 124 125 return iris_init_reset_table(core, &core->controller_resets, 126 core->iris_platform_data->controller_rst_tbl, 127 core->iris_platform_data->controller_rst_tbl_size); 128 } 129 130 static int iris_init_resources(struct iris_core *core) 131 { 132 int ret; 133 134 ret = iris_init_icc(core); 135 if (ret) 136 return ret; 137 138 ret = iris_init_power_domains(core); 139 if (ret) 140 return ret; 141 142 ret = iris_init_clocks(core); 143 if (ret) 144 return ret; 145 146 return iris_init_resets(core); 147 } 148 149 static int iris_register_video_device(struct iris_core *core, enum domain_type type) 150 { 151 struct video_device *vdev; 152 int ret; 153 154 vdev = video_device_alloc(); 155 if (!vdev) 156 return -ENOMEM; 157 158 vdev->release = video_device_release; 159 vdev->fops = core->iris_v4l2_file_ops; 160 vdev->vfl_dir = VFL_DIR_M2M; 161 vdev->v4l2_dev = &core->v4l2_dev; 162 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 163 164 if (type == DECODER) { 165 strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name)); 166 vdev->ioctl_ops = core->iris_v4l2_ioctl_ops_dec; 167 core->vdev_dec = vdev; 168 } else if (type == ENCODER) { 169 strscpy(vdev->name, "qcom-iris-encoder", sizeof(vdev->name)); 170 vdev->ioctl_ops = core->iris_v4l2_ioctl_ops_enc; 171 core->vdev_enc = vdev; 172 } else { 173 ret = -EINVAL; 174 goto err_vdev_release; 175 } 176 177 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 178 if (ret) 179 goto err_vdev_release; 180 181 video_set_drvdata(vdev, core); 182 183 return 0; 184 185 err_vdev_release: 186 video_device_release(vdev); 187 188 return ret; 189 } 190 191 static void iris_remove(struct platform_device *pdev) 192 { 193 struct iris_core *core; 194 195 core = platform_get_drvdata(pdev); 196 if (!core) 197 return; 198 199 iris_core_deinit(core); 200 201 video_unregister_device(core->vdev_dec); 202 video_unregister_device(core->vdev_enc); 203 204 v4l2_device_unregister(&core->v4l2_dev); 205 206 mutex_destroy(&core->lock); 207 } 208 209 static void iris_sys_error_handler(struct work_struct *work) 210 { 211 struct iris_core *core = 212 container_of(work, struct iris_core, sys_error_handler.work); 213 214 iris_core_deinit(core); 215 iris_core_init(core); 216 } 217 218 static int iris_probe(struct platform_device *pdev) 219 { 220 struct device *dev = &pdev->dev; 221 struct iris_core *core; 222 u64 dma_mask; 223 int ret; 224 225 core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); 226 if (!core) 227 return -ENOMEM; 228 core->dev = dev; 229 230 core->state = IRIS_CORE_DEINIT; 231 mutex_init(&core->lock); 232 init_completion(&core->core_init_done); 233 234 core->response_packet = devm_kzalloc(core->dev, IFACEQ_CORE_PKT_SIZE, GFP_KERNEL); 235 if (!core->response_packet) 236 return -ENOMEM; 237 238 INIT_LIST_HEAD(&core->instances); 239 INIT_DELAYED_WORK(&core->sys_error_handler, iris_sys_error_handler); 240 241 core->reg_base = devm_platform_ioremap_resource(pdev, 0); 242 if (IS_ERR(core->reg_base)) 243 return PTR_ERR(core->reg_base); 244 245 core->irq = platform_get_irq(pdev, 0); 246 if (core->irq < 0) 247 return core->irq; 248 249 core->iris_platform_data = of_device_get_match_data(core->dev); 250 251 ret = devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr, 252 iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core); 253 if (ret) 254 return ret; 255 256 disable_irq_nosync(core->irq); 257 258 iris_init_ops(core); 259 core->iris_platform_data->init_hfi_command_ops(core); 260 core->iris_platform_data->init_hfi_response_ops(core); 261 262 ret = iris_init_resources(core); 263 if (ret) 264 return ret; 265 266 iris_session_init_caps(core); 267 268 ret = v4l2_device_register(dev, &core->v4l2_dev); 269 if (ret) 270 return ret; 271 272 ret = iris_register_video_device(core, DECODER); 273 if (ret) 274 goto err_v4l2_unreg; 275 276 ret = iris_register_video_device(core, ENCODER); 277 if (ret) 278 goto err_vdev_unreg_dec; 279 280 platform_set_drvdata(pdev, core); 281 282 dma_mask = core->iris_platform_data->dma_mask; 283 284 ret = dma_set_mask_and_coherent(dev, dma_mask); 285 if (ret) 286 goto err_vdev_unreg_enc; 287 288 dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); 289 dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32)); 290 291 pm_runtime_set_autosuspend_delay(core->dev, AUTOSUSPEND_DELAY_VALUE); 292 pm_runtime_use_autosuspend(core->dev); 293 ret = devm_pm_runtime_enable(core->dev); 294 if (ret) 295 goto err_vdev_unreg_enc; 296 297 return 0; 298 299 err_vdev_unreg_enc: 300 video_unregister_device(core->vdev_enc); 301 err_vdev_unreg_dec: 302 video_unregister_device(core->vdev_dec); 303 err_v4l2_unreg: 304 v4l2_device_unregister(&core->v4l2_dev); 305 306 return ret; 307 } 308 309 static int __maybe_unused iris_pm_suspend(struct device *dev) 310 { 311 struct iris_core *core; 312 int ret = 0; 313 314 core = dev_get_drvdata(dev); 315 316 mutex_lock(&core->lock); 317 if (core->state != IRIS_CORE_INIT) 318 goto exit; 319 320 ret = iris_hfi_pm_suspend(core); 321 322 exit: 323 mutex_unlock(&core->lock); 324 325 return ret; 326 } 327 328 static int __maybe_unused iris_pm_resume(struct device *dev) 329 { 330 struct iris_core *core; 331 int ret = 0; 332 333 core = dev_get_drvdata(dev); 334 335 mutex_lock(&core->lock); 336 if (core->state != IRIS_CORE_INIT) 337 goto exit; 338 339 ret = iris_hfi_pm_resume(core); 340 pm_runtime_mark_last_busy(core->dev); 341 342 exit: 343 mutex_unlock(&core->lock); 344 345 return ret; 346 } 347 348 static const struct dev_pm_ops iris_pm_ops = { 349 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 350 pm_runtime_force_resume) 351 SET_RUNTIME_PM_OPS(iris_pm_suspend, iris_pm_resume, NULL) 352 }; 353 354 static const struct of_device_id iris_dt_match[] = { 355 { 356 .compatible = "qcom,qcs8300-iris", 357 .data = &qcs8300_data, 358 }, 359 #if (!IS_ENABLED(CONFIG_VIDEO_QCOM_VENUS)) 360 { 361 .compatible = "qcom,sm8250-venus", 362 .data = &sm8250_data, 363 }, 364 #endif 365 { 366 .compatible = "qcom,sm8550-iris", 367 .data = &sm8550_data, 368 }, 369 { 370 .compatible = "qcom,sm8650-iris", 371 .data = &sm8650_data, 372 }, 373 { 374 .compatible = "qcom,sm8750-iris", 375 .data = &sm8750_data, 376 }, 377 { }, 378 }; 379 MODULE_DEVICE_TABLE(of, iris_dt_match); 380 381 static struct platform_driver qcom_iris_driver = { 382 .probe = iris_probe, 383 .remove = iris_remove, 384 .driver = { 385 .name = "qcom-iris", 386 .of_match_table = iris_dt_match, 387 .pm = &iris_pm_ops, 388 }, 389 }; 390 391 module_platform_driver(qcom_iris_driver); 392 MODULE_DESCRIPTION("Qualcomm iris video driver"); 393 MODULE_LICENSE("GPL"); 394