1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c 4 * 5 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 6 * http://www.samsung.com/ 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/err.h> 11 #include <linux/firmware.h> 12 #include <linux/jiffies.h> 13 #include <linux/sched.h> 14 #include "s5p_mfc_cmd.h" 15 #include "s5p_mfc_common.h" 16 #include "s5p_mfc_debug.h" 17 #include "s5p_mfc_intr.h" 18 #include "s5p_mfc_opr.h" 19 #include "s5p_mfc_pm.h" 20 #include "s5p_mfc_ctrl.h" 21 22 /* Allocate memory for firmware */ 23 int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev) 24 { 25 struct s5p_mfc_priv_buf *fw_buf = &dev->fw_buf; 26 int err; 27 28 fw_buf->size = dev->variant->buf_size->fw; 29 30 if (fw_buf->virt) { 31 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n"); 32 return -ENOMEM; 33 } 34 35 err = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &dev->fw_buf); 36 if (err) { 37 mfc_err("Allocating bitprocessor buffer failed\n"); 38 return err; 39 } 40 41 return 0; 42 } 43 44 /* Load firmware */ 45 int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev) 46 { 47 struct firmware *fw_blob; 48 int i, err = -EINVAL; 49 50 /* Firmware has to be present as a separate file or compiled 51 * into kernel. */ 52 mfc_debug_enter(); 53 54 /* In case of MFC v12, RET_SYS_INIT response from hardware fails due to 55 * incorrect firmware transfer and therefore it is not able to initialize 56 * the hardware. This causes failed response for SYS_INIT command when 57 * MFC runs for second time. So, load the MFC v12 firmware for each run. 58 */ 59 if (!IS_MFCV12(dev)) 60 if (dev->fw_get_done) 61 return 0; 62 63 for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) { 64 if (!dev->variant->fw_name[i]) 65 continue; 66 err = request_firmware((const struct firmware **)&fw_blob, 67 dev->variant->fw_name[i], &dev->plat_dev->dev); 68 if (!err) { 69 dev->fw_ver = (enum s5p_mfc_fw_ver) i; 70 break; 71 } 72 } 73 74 if (err != 0) { 75 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 76 return -EINVAL; 77 } 78 if (fw_blob->size > dev->fw_buf.size) { 79 mfc_err("MFC firmware is too big to be loaded\n"); 80 release_firmware(fw_blob); 81 return -ENOMEM; 82 } 83 memcpy(dev->fw_buf.virt, fw_blob->data, fw_blob->size); 84 wmb(); 85 dev->fw_get_done = true; 86 release_firmware(fw_blob); 87 mfc_debug_leave(); 88 return 0; 89 } 90 91 /* Release firmware memory */ 92 int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev) 93 { 94 /* Before calling this function one has to make sure 95 * that MFC is no longer processing */ 96 s5p_mfc_release_priv_buf(dev, &dev->fw_buf); 97 dev->fw_get_done = false; 98 return 0; 99 } 100 101 static int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) 102 { 103 unsigned int status; 104 unsigned long timeout; 105 106 /* Reset */ 107 mfc_write(dev, 0x1, S5P_FIMV_MFC_BUS_RESET_CTRL); 108 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT); 109 /* Check bus status */ 110 do { 111 if (time_after(jiffies, timeout)) { 112 mfc_err("Timeout while resetting MFC.\n"); 113 return -EIO; 114 } 115 status = mfc_read(dev, S5P_FIMV_MFC_BUS_RESET_CTRL); 116 } while ((status & 0x2) == 0); 117 return 0; 118 } 119 120 /* Reset the device */ 121 int s5p_mfc_reset(struct s5p_mfc_dev *dev) 122 { 123 unsigned int mc_status; 124 unsigned long timeout; 125 int i; 126 127 mfc_debug_enter(); 128 129 if (IS_MFCV6_PLUS(dev)) { 130 /* Zero Initialization of MFC registers */ 131 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); 132 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6); 133 mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6); 134 135 for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++) 136 mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4)); 137 138 /* check bus reset control before reset */ 139 if (dev->risc_on && !IS_MFCV12(dev)) 140 if (s5p_mfc_bus_reset(dev)) 141 return -EIO; 142 /* Reset 143 * set RISC_ON to 0 during power_on & wake_up. 144 * V6 needs RISC_ON set to 0 during reset also. 145 */ 146 if ((!dev->risc_on) || (!IS_MFCV7_PLUS(dev))) 147 mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); 148 149 mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6); 150 mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6); 151 } else { 152 /* Stop procedure */ 153 /* reset RISC */ 154 mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET); 155 /* All reset except for MC */ 156 mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET); 157 mdelay(10); 158 159 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT); 160 /* Check MC status */ 161 do { 162 if (time_after(jiffies, timeout)) { 163 mfc_err("Timeout while resetting MFC\n"); 164 return -EIO; 165 } 166 167 mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS); 168 169 } while (mc_status & 0x3); 170 171 mfc_write(dev, 0x0, S5P_FIMV_SW_RESET); 172 mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET); 173 } 174 175 mfc_debug_leave(); 176 return 0; 177 } 178 179 static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev) 180 { 181 if (IS_MFCV6_PLUS(dev)) { 182 mfc_write(dev, dev->dma_base[BANK_L_CTX], 183 S5P_FIMV_RISC_BASE_ADDRESS_V6); 184 mfc_debug(2, "Base Address : %pad\n", 185 &dev->dma_base[BANK_L_CTX]); 186 } else { 187 mfc_write(dev, dev->dma_base[BANK_L_CTX], 188 S5P_FIMV_MC_DRAMBASE_ADR_A); 189 mfc_write(dev, dev->dma_base[BANK_R_CTX], 190 S5P_FIMV_MC_DRAMBASE_ADR_B); 191 mfc_debug(2, "Bank1: %pad, Bank2: %pad\n", 192 &dev->dma_base[BANK_L_CTX], 193 &dev->dma_base[BANK_R_CTX]); 194 } 195 } 196 197 static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev) 198 { 199 if (IS_MFCV6_PLUS(dev)) { 200 /* Zero initialization should be done before RESET. 201 * Nothing to do here. */ 202 } else { 203 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID); 204 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID); 205 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD); 206 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD); 207 } 208 } 209 210 /* Initialize hardware */ 211 int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) 212 { 213 unsigned int ver; 214 int ret; 215 216 mfc_debug_enter(); 217 if (!dev->fw_buf.virt) { 218 mfc_err("Firmware memory is not allocated.\n"); 219 return -EINVAL; 220 } 221 222 /* 0. MFC reset */ 223 mfc_debug(2, "MFC reset..\n"); 224 s5p_mfc_clock_on(dev); 225 dev->risc_on = 0; 226 ret = s5p_mfc_reset(dev); 227 if (ret) { 228 mfc_err("Failed to reset MFC - timeout\n"); 229 return ret; 230 } 231 mfc_debug(2, "Done MFC reset..\n"); 232 /* 1. Set DRAM base Addr */ 233 s5p_mfc_init_memctrl(dev); 234 /* 2. Initialize registers of channel I/F */ 235 s5p_mfc_clear_cmds(dev); 236 /* 3. Release reset signal to the RISC */ 237 s5p_mfc_clean_dev_int_flags(dev); 238 if (IS_MFCV6_PLUS(dev)) { 239 dev->risc_on = 1; 240 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); 241 } 242 else 243 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); 244 245 if (IS_MFCV10_PLUS(dev)) 246 mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10); 247 248 mfc_debug(2, "Will now wait for completion of firmware transfer\n"); 249 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { 250 mfc_err("Failed to load firmware\n"); 251 s5p_mfc_reset(dev); 252 s5p_mfc_clock_off(dev); 253 return -EIO; 254 } 255 s5p_mfc_clean_dev_int_flags(dev); 256 /* 4. Initialize firmware */ 257 ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev); 258 if (ret) { 259 mfc_err("Failed to send command to MFC - timeout\n"); 260 s5p_mfc_reset(dev); 261 s5p_mfc_clock_off(dev); 262 return ret; 263 } 264 mfc_debug(2, "Ok, now will wait for completion of hardware init\n"); 265 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) { 266 mfc_err("Failed to init hardware\n"); 267 s5p_mfc_reset(dev); 268 s5p_mfc_clock_off(dev); 269 return -EIO; 270 } 271 dev->int_cond = 0; 272 if (dev->int_err != 0 || dev->int_type != 273 S5P_MFC_R2H_CMD_SYS_INIT_RET) { 274 /* Failure. */ 275 mfc_err("Failed to init firmware - error: %d int: %d\n", 276 dev->int_err, dev->int_type); 277 s5p_mfc_reset(dev); 278 s5p_mfc_clock_off(dev); 279 return -EIO; 280 } 281 if (IS_MFCV6_PLUS(dev)) 282 ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6); 283 else 284 ver = mfc_read(dev, S5P_FIMV_FW_VERSION); 285 286 mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n", 287 (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF); 288 s5p_mfc_clock_off(dev); 289 mfc_debug_leave(); 290 return 0; 291 } 292 293 294 /* Deinitialize hardware */ 295 void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev) 296 { 297 s5p_mfc_clock_on(dev); 298 299 s5p_mfc_reset(dev); 300 s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev); 301 302 s5p_mfc_clock_off(dev); 303 } 304 305 int s5p_mfc_sleep(struct s5p_mfc_dev *dev) 306 { 307 int ret; 308 309 mfc_debug_enter(); 310 s5p_mfc_clock_on(dev); 311 s5p_mfc_clean_dev_int_flags(dev); 312 ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev); 313 if (ret) { 314 mfc_err("Failed to send command to MFC - timeout\n"); 315 return ret; 316 } 317 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) { 318 mfc_err("Failed to sleep\n"); 319 return -EIO; 320 } 321 s5p_mfc_clock_off(dev); 322 dev->int_cond = 0; 323 if (dev->int_err != 0 || dev->int_type != 324 S5P_MFC_R2H_CMD_SLEEP_RET) { 325 /* Failure. */ 326 mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err, 327 dev->int_type); 328 return -EIO; 329 } 330 mfc_debug_leave(); 331 return ret; 332 } 333 334 static int s5p_mfc_v8_wait_wakeup(struct s5p_mfc_dev *dev) 335 { 336 int ret; 337 338 /* Release reset signal to the RISC */ 339 dev->risc_on = 1; 340 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); 341 342 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { 343 mfc_err("Failed to reset MFCV8\n"); 344 return -EIO; 345 } 346 mfc_debug(2, "Write command to wakeup MFCV8\n"); 347 ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); 348 if (ret) { 349 mfc_err("Failed to send command to MFCV8 - timeout\n"); 350 return ret; 351 } 352 353 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { 354 mfc_err("Failed to wakeup MFC\n"); 355 return -EIO; 356 } 357 return ret; 358 } 359 360 static int s5p_mfc_wait_wakeup(struct s5p_mfc_dev *dev) 361 { 362 int ret; 363 364 /* Send MFC wakeup command */ 365 ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); 366 if (ret) { 367 mfc_err("Failed to send command to MFC - timeout\n"); 368 return ret; 369 } 370 371 /* Release reset signal to the RISC */ 372 if (IS_MFCV6_PLUS(dev)) { 373 dev->risc_on = 1; 374 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); 375 } else { 376 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); 377 } 378 379 if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { 380 mfc_err("Failed to wakeup MFC\n"); 381 return -EIO; 382 } 383 return ret; 384 } 385 386 int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) 387 { 388 int ret; 389 390 mfc_debug_enter(); 391 /* 0. MFC reset */ 392 mfc_debug(2, "MFC reset..\n"); 393 s5p_mfc_clock_on(dev); 394 dev->risc_on = 0; 395 ret = s5p_mfc_reset(dev); 396 if (ret) { 397 mfc_err("Failed to reset MFC - timeout\n"); 398 s5p_mfc_clock_off(dev); 399 return ret; 400 } 401 mfc_debug(2, "Done MFC reset..\n"); 402 /* 1. Set DRAM base Addr */ 403 s5p_mfc_init_memctrl(dev); 404 /* 2. Initialize registers of channel I/F */ 405 s5p_mfc_clear_cmds(dev); 406 s5p_mfc_clean_dev_int_flags(dev); 407 /* 3. Send MFC wakeup command and wait for completion*/ 408 if (IS_MFCV8_PLUS(dev)) 409 ret = s5p_mfc_v8_wait_wakeup(dev); 410 else 411 ret = s5p_mfc_wait_wakeup(dev); 412 413 s5p_mfc_clock_off(dev); 414 if (ret) 415 return ret; 416 417 dev->int_cond = 0; 418 if (dev->int_err != 0 || dev->int_type != 419 S5P_MFC_R2H_CMD_WAKEUP_RET) { 420 /* Failure. */ 421 mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err, 422 dev->int_type); 423 return -EIO; 424 } 425 mfc_debug_leave(); 426 return 0; 427 } 428 429 int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) 430 { 431 int ret = 0; 432 433 ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx); 434 if (ret) { 435 mfc_err("Failed allocating instance buffer\n"); 436 goto err; 437 } 438 439 if (ctx->type == MFCINST_DECODER) { 440 ret = s5p_mfc_hw_call(dev->mfc_ops, 441 alloc_dec_temp_buffers, ctx); 442 if (ret) { 443 mfc_err("Failed allocating temporary buffers\n"); 444 goto err_free_inst_buf; 445 } 446 } 447 448 set_work_bit_irqsave(ctx); 449 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); 450 if (s5p_mfc_wait_for_done_ctx(ctx, 451 S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { 452 /* Error or timeout */ 453 mfc_err("Error getting instance from hardware\n"); 454 ret = -EIO; 455 goto err_free_desc_buf; 456 } 457 458 mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); 459 return ret; 460 461 err_free_desc_buf: 462 if (ctx->type == MFCINST_DECODER) 463 s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx); 464 err_free_inst_buf: 465 s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); 466 err: 467 return ret; 468 } 469 470 void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) 471 { 472 ctx->state = MFCINST_RETURN_INST; 473 set_work_bit_irqsave(ctx); 474 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); 475 /* Wait until instance is returned or timeout occurred */ 476 if (s5p_mfc_wait_for_done_ctx(ctx, 477 S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){ 478 clear_work_bit_irqsave(ctx); 479 mfc_err("Err returning instance\n"); 480 } 481 482 /* Free resources */ 483 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); 484 s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); 485 if (ctx->type == MFCINST_DECODER) 486 s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx); 487 488 ctx->inst_no = MFC_NO_INSTANCE_SET; 489 ctx->state = MFCINST_FREE; 490 } 491