diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 19880da4..97649b19 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -914,6 +914,12 @@ static int gk20a_pm_finalize_poweron(struct device *dev) | |||
914 | goto done; | 914 | goto done; |
915 | } | 915 | } |
916 | 916 | ||
917 | err = gk20a_init_gpu_characteristics(g); | ||
918 | if (err) { | ||
919 | nvhost_err(&dev->dev, "failed to init gk20a gpu characteristics"); | ||
920 | goto done; | ||
921 | } | ||
922 | |||
917 | gk20a_channel_resume(g); | 923 | gk20a_channel_resume(g); |
918 | set_user_nice(current, nice_value); | 924 | set_user_nice(current, nice_value); |
919 | 925 | ||
@@ -1577,11 +1583,74 @@ void gk20a_reset(struct gk20a *g, u32 units) | |||
1577 | gk20a_enable(g, units); | 1583 | gk20a_enable(g, units); |
1578 | } | 1584 | } |
1579 | 1585 | ||
1586 | static u32 gk20a_determine_L2_size_bytes(struct gk20a *g) | ||
1587 | { | ||
1588 | const u32 gpuid = GK20A_GPUID(g->gpu_characteristics.arch, | ||
1589 | g->gpu_characteristics.impl); | ||
1590 | u32 lts_per_ltc; | ||
1591 | u32 ways; | ||
1592 | u32 sets; | ||
1593 | u32 bytes_per_line; | ||
1594 | u32 active_ltcs; | ||
1595 | u32 cache_size; | ||
1596 | |||
1597 | u32 tmp; | ||
1598 | u32 active_sets_value; | ||
1599 | |||
1600 | tmp = gk20a_readl(g, ltc_ltc0_lts0_tstg_cfg1_r()); | ||
1601 | ways = hweight32(ltc_ltc0_lts0_tstg_cfg1_active_ways_v(tmp)); | ||
1602 | |||
1603 | active_sets_value = ltc_ltc0_lts0_tstg_cfg1_active_sets_v(tmp); | ||
1604 | if (active_sets_value == ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v()) { | ||
1605 | sets = 64; | ||
1606 | } else if (active_sets_value == | ||
1607 | ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v()) { | ||
1608 | sets = 32; | ||
1609 | } else if (active_sets_value == | ||
1610 | ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v()) { | ||
1611 | sets = 16; | ||
1612 | } else { | ||
1613 | dev_err(dev_from_gk20a(g), | ||
1614 | "Unknown constant %u for active sets", | ||
1615 | (unsigned)active_sets_value); | ||
1616 | sets = 0; | ||
1617 | } | ||
1618 | |||
1619 | active_ltcs = g->gr.num_fbps; | ||
1620 | |||
1621 | /* chip-specific values */ | ||
1622 | switch (gpuid) { | ||
1623 | case GK20A_GPUID_GK20A: | ||
1624 | lts_per_ltc = 1; | ||
1625 | bytes_per_line = 128; | ||
1626 | break; | ||
1627 | |||
1628 | default: | ||
1629 | dev_err(dev_from_gk20a(g), "Unknown GPU id 0x%02x\n", | ||
1630 | (unsigned)gpuid); | ||
1631 | lts_per_ltc = 0; | ||
1632 | bytes_per_line = 0; | ||
1633 | } | ||
1634 | |||
1635 | cache_size = active_ltcs * lts_per_ltc * ways * sets * bytes_per_line; | ||
1636 | |||
1637 | return cache_size; | ||
1638 | } | ||
1639 | |||
1580 | int gk20a_init_gpu_characteristics(struct gk20a *g) | 1640 | int gk20a_init_gpu_characteristics(struct gk20a *g) |
1581 | { | 1641 | { |
1582 | struct nvhost_gpu_characteristics *gpu = &g->gpu_characteristics; | 1642 | struct nvhost_gpu_characteristics *gpu = &g->gpu_characteristics; |
1583 | 1643 | ||
1584 | gpu->L2_cache_size = g->ops.ltc.determine_L2_size_bytes(g); | 1644 | u32 mc_boot_0_value; |
1645 | mc_boot_0_value = gk20a_readl(g, mc_boot_0_r()); | ||
1646 | gpu->arch = mc_boot_0_architecture_v(mc_boot_0_value) << | ||
1647 | NVHOST_GPU_ARCHITECTURE_SHIFT; | ||
1648 | gpu->impl = mc_boot_0_implementation_v(mc_boot_0_value); | ||
1649 | gpu->rev = | ||
1650 | (mc_boot_0_major_revision_v(mc_boot_0_value) << 4) | | ||
1651 | mc_boot_0_minor_revision_v(mc_boot_0_value); | ||
1652 | |||
1653 | gpu->L2_cache_size = gk20a_determine_L2_size_bytes(g); | ||
1585 | gpu->on_board_video_memory_size = 0; /* integrated GPU */ | 1654 | gpu->on_board_video_memory_size = 0; /* integrated GPU */ |
1586 | 1655 | ||
1587 | gpu->num_gpc = g->gr.gpc_count; | 1656 | gpu->num_gpc = g->gr.gpc_count; |