| .. | .. |
|---|
| 26 | 26 | static struct hrtimer timer; |
|---|
| 27 | 27 | static ktime_t kt; |
|---|
| 28 | 28 | |
|---|
| 29 | | -static const struct rga_backend_ops rga3_ops = { |
|---|
| 30 | | - .get_version = rga3_get_version, |
|---|
| 31 | | - .set_reg = rga3_set_reg, |
|---|
| 32 | | - .init_reg = rga3_init_reg, |
|---|
| 33 | | - .soft_reset = rga3_soft_reset |
|---|
| 34 | | -}; |
|---|
| 35 | | - |
|---|
| 36 | | -static const struct rga_backend_ops rga2_ops = { |
|---|
| 37 | | - .get_version = rga2_get_version, |
|---|
| 38 | | - .set_reg = rga2_set_reg, |
|---|
| 39 | | - .init_reg = rga2_init_reg, |
|---|
| 40 | | - .soft_reset = rga2_soft_reset |
|---|
| 41 | | -}; |
|---|
| 42 | | - |
|---|
| 43 | 29 | static struct rga_session *rga_session_init(void); |
|---|
| 44 | 30 | static int rga_session_deinit(struct rga_session *session); |
|---|
| 45 | 31 | |
|---|
| .. | .. |
|---|
| 49 | 35 | { |
|---|
| 50 | 36 | struct rga_external_buffer buffer; |
|---|
| 51 | 37 | |
|---|
| 38 | + memset(&buffer, 0x0, sizeof(buffer)); |
|---|
| 52 | 39 | buffer.memory = (unsigned long)dma_buf; |
|---|
| 53 | 40 | buffer.type = RGA_DMA_BUFFER_PTR; |
|---|
| 54 | 41 | buffer.memory_parm.width = channel_info->vir_w; |
|---|
| .. | .. |
|---|
| 270 | 257 | struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; |
|---|
| 271 | 258 | |
|---|
| 272 | 259 | session = rga_session_init(); |
|---|
| 273 | | - if (!session) |
|---|
| 274 | | - return -ENOMEM; |
|---|
| 260 | + if (IS_ERR(session)) |
|---|
| 261 | + return PTR_ERR(session); |
|---|
| 275 | 262 | |
|---|
| 276 | 263 | request_id = rga_request_alloc(0, session); |
|---|
| 277 | 264 | if (request_id < 0) { |
|---|
| .. | .. |
|---|
| 561 | 548 | |
|---|
| 562 | 549 | static struct rga_session *rga_session_init(void) |
|---|
| 563 | 550 | { |
|---|
| 551 | + int new_id; |
|---|
| 552 | + |
|---|
| 564 | 553 | struct rga_session_manager *session_manager = NULL; |
|---|
| 565 | | - struct rga_session *session = kzalloc(sizeof(*session), GFP_KERNEL); |
|---|
| 554 | + struct rga_session *session = NULL; |
|---|
| 566 | 555 | |
|---|
| 567 | 556 | session_manager = rga_drvdata->session_manager; |
|---|
| 568 | 557 | if (session_manager == NULL) { |
|---|
| 569 | 558 | pr_err("rga_session_manager is null!\n"); |
|---|
| 570 | | - kfree(session); |
|---|
| 571 | | - return NULL; |
|---|
| 559 | + return ERR_PTR(-EFAULT); |
|---|
| 560 | + } |
|---|
| 561 | + |
|---|
| 562 | + session = kzalloc(sizeof(*session), GFP_KERNEL); |
|---|
| 563 | + if (!session) { |
|---|
| 564 | + pr_err("rga_session alloc failed\n"); |
|---|
| 565 | + return ERR_PTR(-ENOMEM); |
|---|
| 572 | 566 | } |
|---|
| 573 | 567 | |
|---|
| 574 | 568 | mutex_lock(&session_manager->lock); |
|---|
| 575 | 569 | |
|---|
| 576 | 570 | idr_preload(GFP_KERNEL); |
|---|
| 577 | | - session->id = idr_alloc(&session_manager->ctx_id_idr, session, 1, 0, GFP_ATOMIC); |
|---|
| 578 | | - session_manager->session_cnt++; |
|---|
| 571 | + new_id = idr_alloc_cyclic(&session_manager->ctx_id_idr, session, 1, 0, GFP_NOWAIT); |
|---|
| 579 | 572 | idr_preload_end(); |
|---|
| 573 | + if (new_id < 0) { |
|---|
| 574 | + mutex_unlock(&session_manager->lock); |
|---|
| 575 | + |
|---|
| 576 | + pr_err("rga_session alloc id failed!\n"); |
|---|
| 577 | + kfree(session); |
|---|
| 578 | + return ERR_PTR(new_id); |
|---|
| 579 | + } |
|---|
| 580 | + |
|---|
| 581 | + session->id = new_id; |
|---|
| 582 | + session_manager->session_cnt++; |
|---|
| 580 | 583 | |
|---|
| 581 | 584 | mutex_unlock(&session_manager->lock); |
|---|
| 582 | 585 | |
|---|
| .. | .. |
|---|
| 588 | 591 | |
|---|
| 589 | 592 | static int rga_session_deinit(struct rga_session *session) |
|---|
| 590 | 593 | { |
|---|
| 591 | | - pid_t pid; |
|---|
| 592 | | - int request_id; |
|---|
| 593 | | - struct rga_pending_request_manager *request_manager; |
|---|
| 594 | | - struct rga_request *request; |
|---|
| 595 | | - |
|---|
| 596 | | - pid = current->pid; |
|---|
| 597 | | - |
|---|
| 598 | | - request_manager = rga_drvdata->pend_request_manager; |
|---|
| 599 | | - |
|---|
| 600 | | - mutex_lock(&request_manager->lock); |
|---|
| 601 | | - |
|---|
| 602 | | - idr_for_each_entry(&request_manager->request_idr, request, request_id) { |
|---|
| 603 | | - |
|---|
| 604 | | - if (session == request->session) { |
|---|
| 605 | | - pr_err("[pid:%d] destroy request[%d] when the user exits", |
|---|
| 606 | | - pid, request->id); |
|---|
| 607 | | - rga_request_put(request); |
|---|
| 608 | | - } |
|---|
| 609 | | - } |
|---|
| 610 | | - |
|---|
| 611 | | - mutex_unlock(&request_manager->lock); |
|---|
| 612 | | - |
|---|
| 613 | | - rga_job_session_destroy(session); |
|---|
| 594 | + rga_request_session_destroy_abort(session); |
|---|
| 614 | 595 | rga_mm_session_release_buffer(session); |
|---|
| 615 | 596 | |
|---|
| 616 | 597 | rga_session_free_remove_idr(session); |
|---|
| .. | .. |
|---|
| 670 | 651 | |
|---|
| 671 | 652 | ret = rga_mm_import_buffer(&external_buffer[i], session); |
|---|
| 672 | 653 | if (ret == 0) { |
|---|
| 673 | | - pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = 0x%x\n", |
|---|
| 654 | + pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = %s(0x%x)\n", |
|---|
| 674 | 655 | i, (unsigned long)external_buffer[i].memory, |
|---|
| 656 | + rga_get_memory_type_str(external_buffer[i].type), |
|---|
| 675 | 657 | external_buffer[i].type); |
|---|
| 676 | 658 | |
|---|
| 677 | 659 | goto err_free_external_buffer; |
|---|
| .. | .. |
|---|
| 741 | 723 | |
|---|
| 742 | 724 | ret = rga_mm_release_buffer(external_buffer[i].handle); |
|---|
| 743 | 725 | if (ret < 0) { |
|---|
| 744 | | - pr_err("buffer[%d] mm release buffer failed!\n", i); |
|---|
| 726 | + pr_err("buffer[%d] mm release buffer failed! handle = %d\n", |
|---|
| 727 | + i, external_buffer[i].handle); |
|---|
| 745 | 728 | |
|---|
| 746 | 729 | goto err_free_external_buffer; |
|---|
| 747 | 730 | } |
|---|
| .. | .. |
|---|
| 1140 | 1123 | struct rga_session *session = NULL; |
|---|
| 1141 | 1124 | |
|---|
| 1142 | 1125 | session = rga_session_init(); |
|---|
| 1143 | | - if (!session) |
|---|
| 1144 | | - return -ENOMEM; |
|---|
| 1126 | + if (IS_ERR(session)) |
|---|
| 1127 | + return PTR_ERR(session); |
|---|
| 1145 | 1128 | |
|---|
| 1146 | 1129 | file->private_data = (void *)session; |
|---|
| 1147 | 1130 | |
|---|
| .. | .. |
|---|
| 1157 | 1140 | return 0; |
|---|
| 1158 | 1141 | } |
|---|
| 1159 | 1142 | |
|---|
| 1160 | | -static irqreturn_t rga3_irq_handler(int irq, void *data) |
|---|
| 1143 | +static irqreturn_t rga_irq_handler(int irq, void *data) |
|---|
| 1161 | 1144 | { |
|---|
| 1145 | + irqreturn_t irq_ret = IRQ_NONE; |
|---|
| 1162 | 1146 | struct rga_scheduler_t *scheduler = data; |
|---|
| 1163 | 1147 | |
|---|
| 1164 | | - if (DEBUGGER_EN(INT_FLAG)) |
|---|
| 1165 | | - pr_info("irqthread INT[%x],STATS0[%x], STATS1[%x]\n", |
|---|
| 1166 | | - rga_read(RGA3_INT_RAW, scheduler), |
|---|
| 1167 | | - rga_read(RGA3_STATUS0, scheduler), |
|---|
| 1168 | | - rga_read(RGA3_STATUS1, scheduler)); |
|---|
| 1148 | + if (scheduler->ops->irq) |
|---|
| 1149 | + irq_ret = scheduler->ops->irq(scheduler); |
|---|
| 1169 | 1150 | |
|---|
| 1170 | | - /* TODO: if error interrupt then soft reset hardware */ |
|---|
| 1171 | | - //scheduler->ops->soft_reset(job->core); |
|---|
| 1172 | | - |
|---|
| 1173 | | - /*clear INT */ |
|---|
| 1174 | | - rga_write(1, RGA3_INT_CLR, scheduler); |
|---|
| 1175 | | - |
|---|
| 1176 | | - return IRQ_WAKE_THREAD; |
|---|
| 1151 | + return irq_ret; |
|---|
| 1177 | 1152 | } |
|---|
| 1178 | 1153 | |
|---|
| 1179 | | -static irqreturn_t rga3_irq_thread(int irq, void *data) |
|---|
| 1154 | +static irqreturn_t rga_isr_thread(int irq, void *data) |
|---|
| 1180 | 1155 | { |
|---|
| 1156 | + irqreturn_t irq_ret = IRQ_NONE; |
|---|
| 1181 | 1157 | struct rga_scheduler_t *scheduler = data; |
|---|
| 1182 | 1158 | struct rga_job *job; |
|---|
| 1183 | 1159 | |
|---|
| 1184 | | - job = scheduler->running_job; |
|---|
| 1185 | | - |
|---|
| 1186 | | - if (!job) { |
|---|
| 1187 | | - pr_err("running job is invaild on irq thread\n"); |
|---|
| 1160 | + job = rga_job_done(scheduler); |
|---|
| 1161 | + if (job == NULL) { |
|---|
| 1162 | + pr_err("isr thread invalid job!\n"); |
|---|
| 1188 | 1163 | return IRQ_HANDLED; |
|---|
| 1189 | 1164 | } |
|---|
| 1190 | 1165 | |
|---|
| 1191 | | - if (DEBUGGER_EN(INT_FLAG)) |
|---|
| 1192 | | - pr_info("irq INT[%x], STATS0[%x], STATS1[%x]\n", |
|---|
| 1193 | | - rga_read(RGA3_INT_RAW, scheduler), |
|---|
| 1194 | | - rga_read(RGA3_STATUS0, scheduler), |
|---|
| 1195 | | - rga_read(RGA3_STATUS1, scheduler)); |
|---|
| 1166 | + if (scheduler->ops->isr_thread) |
|---|
| 1167 | + irq_ret = scheduler->ops->isr_thread(job, scheduler); |
|---|
| 1196 | 1168 | |
|---|
| 1197 | | - rga_job_done(scheduler, 0); |
|---|
| 1169 | + rga_request_release_signal(scheduler, job); |
|---|
| 1198 | 1170 | |
|---|
| 1199 | | - return IRQ_HANDLED; |
|---|
| 1200 | | -} |
|---|
| 1171 | + rga_job_next(scheduler); |
|---|
| 1201 | 1172 | |
|---|
| 1202 | | -static irqreturn_t rga2_irq_handler(int irq, void *data) |
|---|
| 1203 | | -{ |
|---|
| 1204 | | - struct rga_scheduler_t *scheduler = data; |
|---|
| 1173 | + rga_power_disable(scheduler); |
|---|
| 1205 | 1174 | |
|---|
| 1206 | | - if (DEBUGGER_EN(INT_FLAG)) |
|---|
| 1207 | | - pr_info("irqthread INT[%x],STATS0[%x]\n", |
|---|
| 1208 | | - rga_read(RGA2_INT, scheduler), rga_read(RGA2_STATUS, |
|---|
| 1209 | | - scheduler)); |
|---|
| 1210 | | - |
|---|
| 1211 | | - /*if error interrupt then soft reset hardware */ |
|---|
| 1212 | | - //warning |
|---|
| 1213 | | - if (rga_read(RGA2_INT, scheduler) & 0x01) { |
|---|
| 1214 | | - pr_err("err irq! INT[%x],STATS0[%x]\n", |
|---|
| 1215 | | - rga_read(RGA2_INT, scheduler), |
|---|
| 1216 | | - rga_read(RGA2_STATUS, scheduler)); |
|---|
| 1217 | | - scheduler->ops->soft_reset(scheduler); |
|---|
| 1218 | | - } |
|---|
| 1219 | | - |
|---|
| 1220 | | - /*clear INT */ |
|---|
| 1221 | | - rga_write(rga_read(RGA2_INT, scheduler) | |
|---|
| 1222 | | - (0x1 << 4) | (0x1 << 5) | (0x1 << 6) | (0x1 << 7) | |
|---|
| 1223 | | - (0x1 << 15) | (0x1 << 16), RGA2_INT, scheduler); |
|---|
| 1224 | | - |
|---|
| 1225 | | - return IRQ_WAKE_THREAD; |
|---|
| 1226 | | -} |
|---|
| 1227 | | - |
|---|
| 1228 | | -static irqreturn_t rga2_irq_thread(int irq, void *data) |
|---|
| 1229 | | -{ |
|---|
| 1230 | | - struct rga_scheduler_t *scheduler = data; |
|---|
| 1231 | | - struct rga_job *job; |
|---|
| 1232 | | - |
|---|
| 1233 | | - job = scheduler->running_job; |
|---|
| 1234 | | - |
|---|
| 1235 | | - if (!job) |
|---|
| 1236 | | - return IRQ_HANDLED; |
|---|
| 1237 | | - |
|---|
| 1238 | | - if (DEBUGGER_EN(INT_FLAG)) |
|---|
| 1239 | | - pr_info("irq INT[%x], STATS0[%x]\n", |
|---|
| 1240 | | - rga_read(RGA2_INT, scheduler), rga_read(RGA2_STATUS, |
|---|
| 1241 | | - scheduler)); |
|---|
| 1242 | | - |
|---|
| 1243 | | - job->rga_command_base.osd_info.cur_flags0 = rga_read(RGA2_OSD_CUR_FLAGS0_OFFSET, |
|---|
| 1244 | | - scheduler); |
|---|
| 1245 | | - job->rga_command_base.osd_info.cur_flags1 = rga_read(RGA2_OSD_CUR_FLAGS1_OFFSET, |
|---|
| 1246 | | - scheduler); |
|---|
| 1247 | | - |
|---|
| 1248 | | - rga_job_done(scheduler, 0); |
|---|
| 1249 | | - |
|---|
| 1250 | | - return IRQ_HANDLED; |
|---|
| 1175 | + return irq_ret; |
|---|
| 1251 | 1176 | } |
|---|
| 1252 | 1177 | |
|---|
| 1253 | 1178 | const struct file_operations rga_fops = { |
|---|
| .. | .. |
|---|
| 1290 | 1215 | "clk_rga3_1", |
|---|
| 1291 | 1216 | }; |
|---|
| 1292 | 1217 | |
|---|
| 1293 | | -static const struct rga_irqs_data_t single_rga2_irqs[] = { |
|---|
| 1294 | | - {"rga2_irq", rga2_irq_handler, rga2_irq_thread} |
|---|
| 1295 | | -}; |
|---|
| 1296 | | - |
|---|
| 1297 | | -static const struct rga_irqs_data_t rga3_core0_irqs[] = { |
|---|
| 1298 | | - {"rga3_core0_irq", rga3_irq_handler, rga3_irq_thread} |
|---|
| 1299 | | -}; |
|---|
| 1300 | | - |
|---|
| 1301 | | -static const struct rga_irqs_data_t rga3_core1_irqs[] = { |
|---|
| 1302 | | - {"rga3_core1_irq", rga3_irq_handler, rga3_irq_thread} |
|---|
| 1303 | | -}; |
|---|
| 1304 | | - |
|---|
| 1305 | 1218 | static const struct rga_match_data_t old_rga2_match_data = { |
|---|
| 1306 | 1219 | .clks = old_rga2_clks, |
|---|
| 1307 | 1220 | .num_clks = ARRAY_SIZE(old_rga2_clks), |
|---|
| 1308 | | - .irqs = single_rga2_irqs, |
|---|
| 1309 | | - .num_irqs = ARRAY_SIZE(single_rga2_irqs) |
|---|
| 1310 | 1221 | }; |
|---|
| 1311 | 1222 | |
|---|
| 1312 | 1223 | static const struct rga_match_data_t rk3588_rga2_match_data = { |
|---|
| 1313 | 1224 | .clks = rk3588_rga2_clks, |
|---|
| 1314 | 1225 | .num_clks = ARRAY_SIZE(rk3588_rga2_clks), |
|---|
| 1315 | | - .irqs = single_rga2_irqs, |
|---|
| 1316 | | - .num_irqs = ARRAY_SIZE(single_rga2_irqs) |
|---|
| 1317 | 1226 | }; |
|---|
| 1318 | 1227 | |
|---|
| 1319 | 1228 | static const struct rga_match_data_t rga3_core0_match_data = { |
|---|
| 1320 | 1229 | .clks = rga3_core_0_clks, |
|---|
| 1321 | 1230 | .num_clks = ARRAY_SIZE(rga3_core_0_clks), |
|---|
| 1322 | | - .irqs = rga3_core0_irqs, |
|---|
| 1323 | | - .num_irqs = ARRAY_SIZE(rga3_core0_irqs) |
|---|
| 1324 | 1231 | }; |
|---|
| 1325 | 1232 | |
|---|
| 1326 | 1233 | static const struct rga_match_data_t rga3_core1_match_data = { |
|---|
| 1327 | 1234 | .clks = rga3_core_1_clks, |
|---|
| 1328 | 1235 | .num_clks = ARRAY_SIZE(rga3_core_1_clks), |
|---|
| 1329 | | - .irqs = rga3_core1_irqs, |
|---|
| 1330 | | - .num_irqs = ARRAY_SIZE(rga3_core1_irqs) |
|---|
| 1331 | 1236 | }; |
|---|
| 1332 | 1237 | |
|---|
| 1333 | 1238 | static const struct of_device_id rga3_core0_dt_ids[] = { |
|---|
| .. | .. |
|---|
| 1439 | 1344 | /* there are irq names in dts */ |
|---|
| 1440 | 1345 | irq = platform_get_irq(pdev, 0); |
|---|
| 1441 | 1346 | if (irq < 0) { |
|---|
| 1442 | | - dev_err(dev, "no irq %s in dts\n", match_data->irqs[0].name); |
|---|
| 1347 | + dev_err(dev, "no irq %s in dts\n", dev_driver_string(dev)); |
|---|
| 1443 | 1348 | return irq; |
|---|
| 1444 | 1349 | } |
|---|
| 1445 | 1350 | |
|---|
| 1446 | 1351 | scheduler->irq = irq; |
|---|
| 1447 | 1352 | |
|---|
| 1448 | | - pr_info("%s, irq = %d, match scheduler\n", match_data->irqs[0].name, irq); |
|---|
| 1353 | + pr_info("%s, irq = %d, match scheduler\n", dev_driver_string(dev), irq); |
|---|
| 1449 | 1354 | |
|---|
| 1450 | 1355 | ret = devm_request_threaded_irq(dev, irq, |
|---|
| 1451 | | - match_data->irqs[0].irq_hdl, |
|---|
| 1452 | | - match_data->irqs[0].irq_thread, |
|---|
| 1356 | + rga_irq_handler, |
|---|
| 1357 | + rga_isr_thread, |
|---|
| 1453 | 1358 | IRQF_SHARED, |
|---|
| 1454 | 1359 | dev_driver_string(dev), scheduler); |
|---|
| 1455 | 1360 | if (ret < 0) { |
|---|
| 1456 | | - pr_err("request irq name: %s failed: %d\n", match_data->irqs[0].name, ret); |
|---|
| 1361 | + pr_err("request irq name: %s failed: %d\n", dev_driver_string(dev), ret); |
|---|
| 1457 | 1362 | return ret; |
|---|
| 1458 | 1363 | } |
|---|
| 1459 | 1364 | |
|---|
| .. | .. |
|---|
| 1695 | 1600 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) |
|---|
| 1696 | 1601 | #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT |
|---|
| 1697 | 1602 | module_init(rga_init); |
|---|
| 1603 | +#elif defined CONFIG_VIDEO_REVERSE_IMAGE |
|---|
| 1604 | +fs_initcall(rga_init); |
|---|
| 1698 | 1605 | #else |
|---|
| 1699 | 1606 | late_initcall(rga_init); |
|---|
| 1700 | 1607 | #endif |
|---|