hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/video/rockchip/mpp/mpp_rkvenc2.c
....@@ -32,6 +32,7 @@
3232 #include <soc/rockchip/rockchip_ipa.h>
3333 #include <soc/rockchip/rockchip_opp_select.h>
3434 #include <soc/rockchip/rockchip_system_monitor.h>
35
+#include <soc/rockchip/rockchip_iommu.h>
3536
3637 #include "mpp_debug.h"
3738 #include "mpp_iommu.h"
....@@ -44,6 +45,8 @@
4445 #define RKVENC_MAX_DCHS_ID 4
4546 #define RKVENC_MAX_SLICE_FIFO_LEN 256
4647 #define RKVENC_SCLR_DONE_STA BIT(2)
48
+#define RKVENC_WDG 0x38
49
+#define TIMEOUT_MS 100
4750
4851 #define to_rkvenc_info(info) \
4952 container_of(info, struct rkvenc_hw_info, hw)
....@@ -127,6 +130,11 @@
127130 #define INT_STA_WBUS_ERR_STA BIT(6)
128131 #define INT_STA_RBUS_ERR_STA BIT(7)
129132 #define INT_STA_WDG_STA BIT(8)
133
+
134
+#define INT_STA_ERROR (INT_STA_BRSP_OTSD_STA | \
135
+ INT_STA_WBUS_ERR_STA | \
136
+ INT_STA_RBUS_ERR_STA | \
137
+ INT_STA_WDG_STA)
130138
131139 #define DCHS_REG_OFFSET (0x304)
132140 #define DCHS_CLASS_OFFSET (33)
....@@ -294,6 +302,7 @@
294302 #ifdef CONFIG_PM_DEVFREQ
295303 struct rockchip_opp_info opp_info;
296304 struct monitor_dev_info *mdev_info;
305
+ struct opp_table *opp_table;
297306 #endif
298307 };
299308
....@@ -1194,6 +1203,7 @@
11941203 struct rkvenc_task *task = to_rkvenc_task(mpp_task);
11951204 struct rkvenc_hw_info *hw = enc->hw_info;
11961205 u32 timing_en = mpp->srv->timing_en;
1206
+ u32 timeout_thd;
11971207
11981208 mpp_debug_enter();
11991209
....@@ -1242,11 +1252,18 @@
12421252 /* init current task */
12431253 mpp->cur_task = mpp_task;
12441254
1255
+ /*
1256
+ * reconfig timeout threshold.
1257
+ * bit0-bit23,x1024 core clk cycles
1258
+ */
1259
+ timeout_thd = mpp_read(mpp, RKVENC_WDG) & 0xff000000;
1260
+ timeout_thd |= TIMEOUT_MS * clk_get_rate(enc->core_clk_info.clk) / 1024000;
1261
+ mpp_write(mpp, RKVENC_WDG, timeout_thd);
1262
+
12451263 mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
12461264
12471265 /* Flush the register before the start the device */
12481266 wmb();
1249
-
12501267 mpp_write(mpp, enc->hw_info->enc_start_base, start_val);
12511268
12521269 mpp_task_run_end(mpp_task, timing_en);
....@@ -1256,9 +1273,9 @@
12561273 return 0;
12571274 }
12581275
1259
-static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task)
1276
+static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task,
1277
+ u32 last)
12601278 {
1261
- u32 last = mpp_read_relaxed(mpp, 0x002c) & INT_STA_ENC_DONE_STA;
12621279 u32 sli_num = mpp_read_relaxed(mpp, RKVENC2_REG_SLICE_NUM_BASE);
12631280 union rkvenc2_slice_len_info slice_info;
12641281 u32 task_id = task->mpp_task.task_id;
....@@ -1298,46 +1315,49 @@
12981315 struct rkvenc_hw_info *hw = enc->hw_info;
12991316 struct mpp_task *mpp_task = NULL;
13001317 struct rkvenc_task *task = NULL;
1301
- u32 int_clear = 1;
1302
- u32 irq_mask = 0;
1318
+ u32 irq_status;
13031319 int ret = IRQ_NONE;
13041320
13051321 mpp_debug_enter();
13061322
1307
- mpp->irq_status = mpp_read(mpp, hw->int_sta_base);
1308
- if (!mpp->irq_status)
1323
+ irq_status = mpp_read(mpp, hw->int_sta_base);
1324
+
1325
+ mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
1326
+ dev_name(mpp->dev), irq_status);
1327
+
1328
+ if (!irq_status)
13091329 return ret;
1330
+
1331
+ /* clear int first */
1332
+ mpp_write(mpp, hw->int_clr_base, irq_status);
1333
+
1334
+ /*
1335
+ * prevent watch dog irq storm.
1336
+ * The encoder did not stop working when watchdog interrupt is triggered,
1337
+ * it still check timeout and trigger watch dog irq.
1338
+ */
1339
+ if (irq_status & INT_STA_WDG_STA)
1340
+ mpp_write(mpp, hw->int_mask_base, INT_STA_WDG_STA);
13101341
13111342 if (mpp->cur_task) {
13121343 mpp_task = mpp->cur_task;
13131344 task = to_rkvenc_task(mpp_task);
13141345 }
13151346
1316
- if (mpp->irq_status & INT_STA_ENC_DONE_STA) {
1317
- if (task) {
1318
- if (task->task_split)
1319
- rkvenc2_read_slice_len(mpp, task);
1347
+ /* 1. read slice number and slice length */
1348
+ if (task && task->task_split &&
1349
+ (irq_status & (INT_STA_SLC_DONE_STA | INT_STA_ENC_DONE_STA))) {
1350
+ mpp_time_part_diff(mpp_task);
1351
+ rkvenc2_read_slice_len(mpp, task, irq_status & INT_STA_ENC_DONE_STA);
1352
+ wake_up(&mpp_task->wait);
1353
+ }
13201354
1321
- wake_up(&mpp_task->wait);
1322
- }
1355
+ /* 2. process slice irq */
1356
+ if (irq_status & INT_STA_SLC_DONE_STA)
1357
+ ret = IRQ_HANDLED;
13231358
1324
- irq_mask = INT_STA_ENC_DONE_STA;
1325
- ret = IRQ_WAKE_THREAD;
1326
- if (enc->bs_overflow) {
1327
- mpp->irq_status |= INT_STA_BSF_OFLW_STA;
1328
- enc->bs_overflow = 0;
1329
- }
1330
- } else if (mpp->irq_status & INT_STA_SLC_DONE_STA) {
1331
- if (task && task->task_split) {
1332
- mpp_time_part_diff(mpp_task);
1333
-
1334
- rkvenc2_read_slice_len(mpp, task);
1335
- wake_up(&mpp_task->wait);
1336
- }
1337
-
1338
- irq_mask = INT_STA_ENC_DONE_STA;
1339
- int_clear = 0;
1340
- } else if (mpp->irq_status & INT_STA_BSF_OFLW_STA) {
1359
+ /* 3. process bitstream overflow */
1360
+ if (irq_status & INT_STA_BSF_OFLW_STA) {
13411361 u32 bs_rd = mpp_read(mpp, RKVENC2_REG_ADR_BSBR);
13421362 u32 bs_wr = mpp_read(mpp, RKVENC2_REG_ST_BSB);
13431363 u32 bs_top = mpp_read(mpp, RKVENC2_REG_ADR_BSBT);
....@@ -1349,33 +1369,43 @@
13491369 bs_wr += 128;
13501370 if (bs_wr >= bs_top)
13511371 bs_wr = bs_bot;
1352
- /* clear int first */
1353
- mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
1372
+
13541373 /* update write addr for enc continue */
13551374 mpp_write(mpp, RKVENC2_REG_ADR_BSBS, bs_wr);
13561375 enc->bs_overflow = 1;
1357
- irq_mask = 0;
1358
- int_clear = 0;
1359
- ret = IRQ_HANDLED;
1360
- } else {
1361
- dev_err(mpp->dev, "found error status %08x\n", mpp->irq_status);
13621376
1363
- irq_mask = mpp->irq_status;
1377
+ ret = IRQ_HANDLED;
1378
+ }
1379
+
1380
+ /* 4. process frame irq */
1381
+ if (irq_status & INT_STA_ENC_DONE_STA) {
1382
+ mpp->irq_status = irq_status;
1383
+
1384
+ if (enc->bs_overflow) {
1385
+ mpp->irq_status |= INT_STA_BSF_OFLW_STA;
1386
+ enc->bs_overflow = 0;
1387
+ }
1388
+
13641389 ret = IRQ_WAKE_THREAD;
13651390 }
13661391
1367
- if (irq_mask)
1368
- mpp_write(mpp, hw->int_mask_base, irq_mask);
1392
+ /* 5. process error irq */
1393
+ if (irq_status & INT_STA_ERROR) {
1394
+ mpp->irq_status = irq_status;
13691395
1370
- if (int_clear) {
1371
- mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
1372
- udelay(5);
1373
- mpp_write(mpp, hw->int_sta_base, 0);
1396
+ dev_err(mpp->dev, "found error status %08x\n", irq_status);
1397
+
1398
+ ret = IRQ_WAKE_THREAD;
13741399 }
13751400
13761401 mpp_debug_leave();
13771402
13781403 return ret;
1404
+}
1405
+
1406
+static int vepu540c_irq(struct mpp_dev *mpp)
1407
+{
1408
+ return rkvenc_irq(mpp);
13791409 }
13801410
13811411 static int rkvenc_isr(struct mpp_dev *mpp)
....@@ -1405,9 +1435,6 @@
14051435 task->irq_status = mpp->irq_status;
14061436
14071437 rkvenc2_update_dchs(enc, task);
1408
-
1409
- mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
1410
- dev_name(mpp->dev), task->irq_status);
14111438
14121439 if (task->irq_status & enc->hw_info->err_mask) {
14131440 atomic_inc(&mpp->reset_request);
....@@ -1458,7 +1485,7 @@
14581485 if (task->bs_buf) {
14591486 u32 bs_size = mpp_read(mpp, 0x4064);
14601487
1461
- mpp_dma_buf_sync(task->bs_buf, 0, bs_size / 8 + task->offset_bs,
1488
+ mpp_dma_buf_sync(task->bs_buf, 0, bs_size + task->offset_bs,
14621489 DMA_FROM_DEVICE, true);
14631490 }
14641491
....@@ -1785,16 +1812,19 @@
17851812 if (IS_ERR(reg_table))
17861813 return PTR_ERR(reg_table);
17871814 }
1815
+ enc->opp_table = reg_table;
17881816
17891817 clk_table = dev_pm_opp_set_clkname(dev, "clk_core");
1790
- if (IS_ERR(clk_table))
1791
- return PTR_ERR(clk_table);
1818
+ if (IS_ERR(clk_table)) {
1819
+ ret = PTR_ERR(clk_table);
1820
+ goto put_opp_reg;
1821
+ }
17921822
17931823 rockchip_get_opp_data(rockchip_rkvenc_of_match, &enc->opp_info);
17941824 ret = rockchip_init_opp_table(dev, &enc->opp_info, "leakage", "venc");
17951825 if (ret) {
17961826 dev_err(dev, "failed to init_opp_table\n");
1797
- return ret;
1827
+ goto put_opp_clk;
17981828 }
17991829
18001830 enc->mdev_info = rockchip_system_monitor_register(dev, &venc_mdevp);
....@@ -1803,6 +1833,14 @@
18031833 enc->mdev_info = NULL;
18041834 }
18051835
1836
+ return 0;
1837
+
1838
+put_opp_clk:
1839
+ dev_pm_opp_put_clkname(enc->opp_table);
1840
+put_opp_reg:
1841
+ dev_pm_opp_put_regulators(enc->opp_table);
1842
+ enc->opp_table = NULL;
1843
+
18061844 return ret;
18071845 }
18081846
....@@ -1810,8 +1848,16 @@
18101848 {
18111849 struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
18121850
1813
- if (enc->mdev_info)
1851
+ if (enc->mdev_info) {
18141852 rockchip_system_monitor_unregister(enc->mdev_info);
1853
+ enc->mdev_info = NULL;
1854
+ }
1855
+ if (enc->opp_table) {
1856
+ rockchip_uninit_opp_table(mpp->dev, &enc->opp_info);
1857
+ dev_pm_opp_put_clkname(enc->opp_table);
1858
+ dev_pm_opp_put_regulators(enc->opp_table);
1859
+ enc->opp_table = NULL;
1860
+ }
18151861
18161862 return 0;
18171863 }
....@@ -1880,7 +1926,7 @@
18801926
18811927 /* safe reset */
18821928 mpp_write(mpp, hw->int_mask_base, 0x3FF);
1883
- mpp_write(mpp, hw->enc_clr_base, 0x1);
1929
+ mpp_write(mpp, hw->enc_clr_base, 0x3);
18841930 ret = readl_relaxed_poll_timeout(mpp->reg_base + hw->int_sta_base,
18851931 rst_status,
18861932 rst_status & RKVENC_SCLR_DONE_STA,
....@@ -2169,6 +2215,20 @@
21692215 .dump_session = rkvenc_dump_session,
21702216 };
21712217
2218
+static struct mpp_dev_ops vepu540c_dev_ops_v2 = {
2219
+ .wait_result = rkvenc2_wait_result,
2220
+ .alloc_task = rkvenc_alloc_task,
2221
+ .run = rkvenc_run,
2222
+ .irq = vepu540c_irq,
2223
+ .isr = rkvenc_isr,
2224
+ .finish = rkvenc_finish,
2225
+ .result = rkvenc_result,
2226
+ .free_task = rkvenc_free_task,
2227
+ .ioctl = rkvenc_control,
2228
+ .init_session = rkvenc_init_session,
2229
+ .free_session = rkvenc_free_session,
2230
+ .dump_session = rkvenc_dump_session,
2231
+};
21722232
21732233 static const struct mpp_dev_var rkvenc_v2_data = {
21742234 .device_type = MPP_DEVICE_RKVENC,
....@@ -2183,7 +2243,7 @@
21832243 .hw_info = &rkvenc_540c_hw_info.hw,
21842244 .trans_info = trans_rkvenc_540c,
21852245 .hw_ops = &rkvenc_hw_ops,
2186
- .dev_ops = &rkvenc_dev_ops_v2,
2246
+ .dev_ops = &vepu540c_dev_ops_v2,
21872247 };
21882248
21892249 static const struct mpp_dev_var rkvenc_ccu_data = {
....@@ -2404,13 +2464,32 @@
24042464 {
24052465 struct mpp_dev *mpp = (struct mpp_dev *)arg;
24062466 struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
2407
- struct mpp_task *mpp_task = mpp->cur_task;
2467
+ struct mpp_task *mpp_task;
2468
+ struct rkvenc_ccu *ccu = enc->ccu;
24082469
2470
+ if (ccu) {
2471
+ struct rkvenc_dev *core = NULL, *n;
2472
+
2473
+ list_for_each_entry_safe(core, n, &ccu->core_list, core_link) {
2474
+ if (core->mpp.iommu_info &&
2475
+ (&core->mpp.iommu_info->pdev->dev == iommu_dev)) {
2476
+ mpp = &core->mpp;
2477
+ break;
2478
+ }
2479
+ }
2480
+ }
2481
+ mpp_task = mpp->cur_task;
24092482 dev_info(mpp->dev, "core %d page fault found dchs %08x\n",
24102483 mpp->core_id, mpp_read_relaxed(&enc->mpp, DCHS_REG_OFFSET));
24112484
24122485 if (mpp_task)
24132486 mpp_task_dump_mem_region(mpp, mpp_task);
2487
+
2488
+ /*
2489
+ * Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
2490
+ * Until the pagefault task finish by hw timeout.
2491
+ */
2492
+ rockchip_iommu_mask_irq(mpp->dev);
24142493
24152494 return 0;
24162495 }
....@@ -2455,7 +2534,7 @@
24552534 ret = devm_request_threaded_irq(dev, mpp->irq,
24562535 mpp_dev_irq,
24572536 mpp_dev_isr_sched,
2458
- IRQF_SHARED,
2537
+ IRQF_ONESHOT,
24592538 dev_name(dev), mpp);
24602539 if (ret) {
24612540 dev_err(dev, "register interrupter runtime failed\n");