diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2017-03-17 14:09:44 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-03-23 11:44:07 -0400 |
commit | 4492c62ffe9398bd4457f6f1c2773e40afe909fb (patch) | |
tree | 5d792f81d97844278f4eca665a8b4778fa93dc35 /drivers/gpu/nvgpu/gk20a/gk20a.c | |
parent | 33f637585ecd617a9f4423f56e2aa6df0691ac64 (diff) |
gpu: nvgpu: Add bus HAL
Add bus HAL and move all bus related hardware sequencing to that file:
BAR1 binding, timer access, and interrupt handling.
Change-Id: Ibc5f5797dc338de10749b446a7bdbcae600fecb4
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/1323353
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 104 |
1 files changed, 2 insertions, 102 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 76484dd5..72528758 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include "hal.h" | 57 | #include "hal.h" |
58 | #include "vgpu/vgpu.h" | 58 | #include "vgpu/vgpu.h" |
59 | #include "pci.h" | 59 | #include "pci.h" |
60 | #include "bus_gk20a.h" | ||
60 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | 61 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC |
61 | #include "pstate/pstate.h" | 62 | #include "pstate/pstate.h" |
62 | #endif | 63 | #endif |
@@ -70,11 +71,8 @@ | |||
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> | 73 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> |
73 | #include <nvgpu/hw/gk20a/hw_timer_gk20a.h> | ||
74 | #include <nvgpu/hw/gk20a/hw_bus_gk20a.h> | ||
75 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> | 74 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> |
76 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> | 75 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> |
77 | #include <nvgpu/hw/gk20a/hw_gr_gk20a.h> | ||
78 | #include <nvgpu/hw/gk20a/hw_fb_gk20a.h> | 76 | #include <nvgpu/hw/gk20a/hw_fb_gk20a.h> |
79 | 77 | ||
80 | 78 | ||
@@ -330,42 +328,6 @@ static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) | |||
330 | return g->ops.mc.isr_nonstall(g); | 328 | return g->ops.mc.isr_nonstall(g); |
331 | } | 329 | } |
332 | 330 | ||
333 | void gk20a_pbus_isr(struct gk20a *g) | ||
334 | { | ||
335 | u32 val, err_code; | ||
336 | val = gk20a_readl(g, bus_intr_0_r()); | ||
337 | if (val & (bus_intr_0_pri_squash_m() | | ||
338 | bus_intr_0_pri_fecserr_m() | | ||
339 | bus_intr_0_pri_timeout_m())) { | ||
340 | gk20a_dbg(gpu_dbg_intr, "pmc_enable : 0x%x", | ||
341 | gk20a_readl(g, mc_enable_r())); | ||
342 | gk20a_dbg(gpu_dbg_intr, "NV_PBUS_INTR_0 : 0x%x", val); | ||
343 | gk20a_dbg(gpu_dbg_intr, | ||
344 | "NV_PTIMER_PRI_TIMEOUT_SAVE_0: 0x%x\n", | ||
345 | gk20a_readl(g, timer_pri_timeout_save_0_r())); | ||
346 | gk20a_dbg(gpu_dbg_intr, | ||
347 | "NV_PTIMER_PRI_TIMEOUT_SAVE_1: 0x%x\n", | ||
348 | gk20a_readl(g, timer_pri_timeout_save_1_r())); | ||
349 | err_code = gk20a_readl(g, timer_pri_timeout_fecs_errcode_r()); | ||
350 | gk20a_dbg(gpu_dbg_intr, | ||
351 | "NV_PTIMER_PRI_TIMEOUT_FECS_ERRCODE: 0x%x\n", | ||
352 | err_code); | ||
353 | if (err_code == 0xbadf13) | ||
354 | gk20a_dbg(gpu_dbg_intr, | ||
355 | "NV_PGRAPH_PRI_GPC0_GPCCS_FS_GPC: 0x%x\n", | ||
356 | gk20a_readl(g, gr_gpc0_fs_gpc_r())); | ||
357 | |||
358 | gk20a_writel(g, timer_pri_timeout_save_0_r(), 0); | ||
359 | gk20a_writel(g, timer_pri_timeout_save_1_r(), 0); | ||
360 | } | ||
361 | |||
362 | if (val) | ||
363 | gk20a_dbg(gpu_dbg_intr, | ||
364 | "Unhandled pending pbus interrupt\n"); | ||
365 | |||
366 | gk20a_writel(g, bus_intr_0_r(), val); | ||
367 | } | ||
368 | |||
369 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | 331 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) |
370 | { | 332 | { |
371 | struct gk20a *g = dev_id; | 333 | struct gk20a *g = dev_id; |
@@ -596,13 +558,7 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
596 | if (err) | 558 | if (err) |
597 | goto done; | 559 | goto done; |
598 | 560 | ||
599 | if (!tegra_platform_is_silicon()) | 561 | g->ops.bus.init_hw(g); |
600 | gk20a_writel(g, bus_intr_en_0_r(), 0x0); | ||
601 | else | ||
602 | gk20a_writel(g, bus_intr_en_0_r(), | ||
603 | bus_intr_en_0_pri_squash_m() | | ||
604 | bus_intr_en_0_pri_fecserr_m() | | ||
605 | bus_intr_en_0_pri_timeout_m()); | ||
606 | 562 | ||
607 | if (g->ops.clk.disable_slowboot) | 563 | if (g->ops.clk.disable_slowboot) |
608 | g->ops.clk.disable_slowboot(g); | 564 | g->ops.clk.disable_slowboot(g); |
@@ -630,22 +586,6 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
630 | } | 586 | } |
631 | } | 587 | } |
632 | 588 | ||
633 | /* enable pri timeout only on silicon */ | ||
634 | if (tegra_platform_is_silicon()) { | ||
635 | gk20a_writel(g, | ||
636 | timer_pri_timeout_r(), | ||
637 | timer_pri_timeout_period_f( | ||
638 | platform->default_pri_timeout ? | ||
639 | platform->default_pri_timeout : | ||
640 | 0x186A0) | | ||
641 | timer_pri_timeout_en_en_enabled_f()); | ||
642 | } else { | ||
643 | gk20a_writel(g, | ||
644 | timer_pri_timeout_r(), | ||
645 | timer_pri_timeout_period_f(0x186A0) | | ||
646 | timer_pri_timeout_en_en_disabled_f()); | ||
647 | } | ||
648 | |||
649 | err = gk20a_init_fifo_reset_enable_hw(g); | 589 | err = gk20a_init_fifo_reset_enable_hw(g); |
650 | if (err) { | 590 | if (err) { |
651 | gk20a_err(dev, "failed to reset gk20a fifo"); | 591 | gk20a_err(dev, "failed to reset gk20a fifo"); |
@@ -1910,46 +1850,6 @@ int gk20a_init_gpu_characteristics(struct gk20a *g) | |||
1910 | return 0; | 1850 | return 0; |
1911 | } | 1851 | } |
1912 | 1852 | ||
1913 | int gk20a_read_ptimer(struct gk20a *g, u64 *value) | ||
1914 | { | ||
1915 | const unsigned int max_iterations = 3; | ||
1916 | unsigned int i = 0; | ||
1917 | u32 gpu_timestamp_hi_prev = 0; | ||
1918 | |||
1919 | if (!value) | ||
1920 | return -EINVAL; | ||
1921 | |||
1922 | /* Note. The GPU nanosecond timer consists of two 32-bit | ||
1923 | * registers (high & low). To detect a possible low register | ||
1924 | * wrap-around between the reads, we need to read the high | ||
1925 | * register before and after low. The wraparound happens | ||
1926 | * approximately once per 4 secs. */ | ||
1927 | |||
1928 | /* get initial gpu_timestamp_hi value */ | ||
1929 | gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r()); | ||
1930 | |||
1931 | for (i = 0; i < max_iterations; ++i) { | ||
1932 | u32 gpu_timestamp_hi = 0; | ||
1933 | u32 gpu_timestamp_lo = 0; | ||
1934 | |||
1935 | gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r()); | ||
1936 | gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r()); | ||
1937 | |||
1938 | if (gpu_timestamp_hi == gpu_timestamp_hi_prev) { | ||
1939 | *value = (((u64)gpu_timestamp_hi) << 32) | | ||
1940 | gpu_timestamp_lo; | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1944 | /* wrap-around detected, retry */ | ||
1945 | gpu_timestamp_hi_prev = gpu_timestamp_hi; | ||
1946 | } | ||
1947 | |||
1948 | /* too many iterations, bail out */ | ||
1949 | gk20a_err(dev_from_gk20a(g), "failed to read ptimer"); | ||
1950 | return -EBUSY; | ||
1951 | } | ||
1952 | |||
1953 | /* | 1853 | /* |
1954 | * Free the gk20a struct. | 1854 | * Free the gk20a struct. |
1955 | */ | 1855 | */ |