diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/acr_gm20b.c')
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index f4311ee9..e47bc773 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c | |||
@@ -18,10 +18,13 @@ | |||
18 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include "nvgpu_common.h" | ||
22 | 21 | ||
23 | #include <linux/platform/tegra/mc.h> | 22 | #include <linux/platform/tegra/mc.h> |
24 | 23 | ||
24 | #include <nvgpu/timers.h> | ||
25 | |||
26 | #include "nvgpu_common.h" | ||
27 | |||
25 | #include "gk20a/gk20a.h" | 28 | #include "gk20a/gk20a.h" |
26 | #include "gk20a/pmu_gk20a.h" | 29 | #include "gk20a/pmu_gk20a.h" |
27 | #include "gk20a/semaphore_gk20a.h" | 30 | #include "gk20a/semaphore_gk20a.h" |
@@ -1476,64 +1479,69 @@ err_done: | |||
1476 | /*! | 1479 | /*! |
1477 | * Wait for PMU to halt | 1480 | * Wait for PMU to halt |
1478 | * @param[in] g GPU object pointer | 1481 | * @param[in] g GPU object pointer |
1479 | * @param[in] timeout Timeout in msec for PMU to halt | 1482 | * @param[in] timeout_ms Timeout in msec for PMU to halt |
1480 | * @return '0' if PMU halts | 1483 | * @return '0' if PMU halts |
1481 | */ | 1484 | */ |
1482 | static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout) | 1485 | static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout_ms) |
1483 | { | 1486 | { |
1484 | u32 data = 0; | 1487 | u32 data = 0; |
1485 | int completion = -EBUSY; | 1488 | int ret = -EBUSY; |
1486 | unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); | 1489 | struct nvgpu_timeout timeout; |
1490 | |||
1491 | nvgpu_timeout_init(g, &timeout, timeout_ms, NVGPU_TIMER_CPU_TIMER); | ||
1487 | 1492 | ||
1488 | while (time_before(jiffies, end_jiffies) || | 1493 | do { |
1489 | !tegra_platform_is_silicon()) { | ||
1490 | data = gk20a_readl(g, pwr_falcon_cpuctl_r()); | 1494 | data = gk20a_readl(g, pwr_falcon_cpuctl_r()); |
1491 | if (data & pwr_falcon_cpuctl_halt_intr_m()) { | 1495 | if (data & pwr_falcon_cpuctl_halt_intr_m()) { |
1492 | /*CPU is halted break*/ | 1496 | /* CPU is halted break */ |
1493 | completion = 0; | 1497 | ret = 0; |
1494 | break; | 1498 | break; |
1495 | } | 1499 | } |
1496 | udelay(1); | 1500 | udelay(1); |
1497 | } | 1501 | } while (!nvgpu_timeout_expired(&timeout)); |
1498 | if (completion) | 1502 | |
1503 | if (ret) { | ||
1499 | gk20a_err(dev_from_gk20a(g), "ACR boot timed out"); | 1504 | gk20a_err(dev_from_gk20a(g), "ACR boot timed out"); |
1500 | else { | 1505 | return ret; |
1501 | g->acr.capabilities = gk20a_readl(g, pwr_falcon_mailbox1_r()); | 1506 | } |
1502 | gm20b_dbg_pmu("ACR capabilities %x\n", g->acr.capabilities); | 1507 | |
1503 | data = gk20a_readl(g, pwr_falcon_mailbox0_r()); | 1508 | g->acr.capabilities = gk20a_readl(g, pwr_falcon_mailbox1_r()); |
1504 | if (data) { | 1509 | gm20b_dbg_pmu("ACR capabilities %x\n", g->acr.capabilities); |
1505 | gk20a_err(dev_from_gk20a(g), | 1510 | data = gk20a_readl(g, pwr_falcon_mailbox0_r()); |
1506 | "ACR boot failed, err %x", data); | 1511 | if (data) { |
1507 | completion = -EAGAIN; | 1512 | gk20a_err(dev_from_gk20a(g), |
1508 | } | 1513 | "ACR boot failed, err %x", data); |
1514 | ret = -EAGAIN; | ||
1509 | } | 1515 | } |
1510 | return completion; | 1516 | |
1517 | return ret; | ||
1511 | } | 1518 | } |
1512 | 1519 | ||
1513 | /*! | 1520 | /*! |
1514 | * Wait for PMU halt interrupt status to be cleared | 1521 | * Wait for PMU halt interrupt status to be cleared |
1515 | * @param[in] g GPU object pointer | 1522 | * @param[in] g GPU object pointer |
1516 | * @param[in] timeout_us Timeout in msec for halt to clear | 1523 | * @param[in] timeout_ms Timeout in msec for halt to clear |
1517 | * @return '0' if PMU halt irq status is clear | 1524 | * @return '0' if PMU halt irq status is clear |
1518 | */ | 1525 | */ |
1519 | static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) | 1526 | static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout_ms) |
1520 | { | 1527 | { |
1521 | u32 data = 0; | 1528 | u32 data = 0; |
1522 | unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); | 1529 | struct nvgpu_timeout timeout; |
1530 | |||
1531 | nvgpu_timeout_init(g, &timeout, timeout_ms, NVGPU_TIMER_CPU_TIMER); | ||
1523 | 1532 | ||
1524 | while (time_before(jiffies, end_jiffies) || | 1533 | do { |
1525 | !tegra_platform_is_silicon()) { | ||
1526 | gk20a_writel(g, pwr_falcon_irqsclr_r(), | 1534 | gk20a_writel(g, pwr_falcon_irqsclr_r(), |
1527 | gk20a_readl(g, pwr_falcon_irqsclr_r()) | (0x10)); | 1535 | gk20a_readl(g, pwr_falcon_irqsclr_r()) | (0x10)); |
1528 | data = gk20a_readl(g, (pwr_falcon_irqstat_r())); | 1536 | data = gk20a_readl(g, (pwr_falcon_irqstat_r())); |
1537 | |||
1529 | if ((data & pwr_falcon_irqstat_halt_true_f()) != | 1538 | if ((data & pwr_falcon_irqstat_halt_true_f()) != |
1530 | pwr_falcon_irqstat_halt_true_f()) | 1539 | pwr_falcon_irqstat_halt_true_f()) |
1531 | /*halt irq is clear*/ | 1540 | /*halt irq is clear*/ |
1532 | break; | 1541 | return 0; |
1533 | timeout--; | 1542 | |
1534 | udelay(1); | 1543 | udelay(1); |
1535 | } | 1544 | } while (!nvgpu_timeout_expired(&timeout)); |
1536 | if (timeout == 0) | 1545 | |
1537 | return -EBUSY; | 1546 | return -ETIMEDOUT; |
1538 | return 0; | ||
1539 | } | 1547 | } |