diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 39 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 46 |
2 files changed, 71 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 7e0183ca..bec18328 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | |||
@@ -520,6 +520,43 @@ static ssize_t force_idle_read(struct device *device, | |||
520 | static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store); | 520 | static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store); |
521 | #endif | 521 | #endif |
522 | 522 | ||
523 | static ssize_t tpc_fs_mask_store(struct device *device, | ||
524 | struct device_attribute *attr, const char *buf, size_t count) | ||
525 | { | ||
526 | struct platform_device *ndev = to_platform_device(device); | ||
527 | struct gk20a *g = get_gk20a(ndev); | ||
528 | unsigned long val = 0; | ||
529 | |||
530 | if (kstrtoul(buf, 10, &val) < 0) | ||
531 | return -EINVAL; | ||
532 | |||
533 | if (val) | ||
534 | g->gr.gpc_tpc_mask[0] = val; | ||
535 | |||
536 | return count; | ||
537 | } | ||
538 | |||
539 | static ssize_t tpc_fs_mask_read(struct device *device, | ||
540 | struct device_attribute *attr, char *buf) | ||
541 | { | ||
542 | struct platform_device *ndev = to_platform_device(device); | ||
543 | struct gk20a *g = get_gk20a(ndev); | ||
544 | struct gr_gk20a *gr = &g->gr; | ||
545 | u32 gpc_index; | ||
546 | u32 tpc_fs_mask = 0; | ||
547 | |||
548 | for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { | ||
549 | if (g->ops.gr.get_gpc_tpc_mask) | ||
550 | tpc_fs_mask |= | ||
551 | g->ops.gr.get_gpc_tpc_mask(g, gpc_index) << | ||
552 | (gr->max_tpc_per_gpc_count * gpc_index); | ||
553 | } | ||
554 | |||
555 | return sprintf(buf, "0x%x\n", tpc_fs_mask); | ||
556 | } | ||
557 | |||
558 | static DEVICE_ATTR(tpc_fs_mask, S_IRWXUGO, tpc_fs_mask_read, tpc_fs_mask_store); | ||
559 | |||
523 | void gk20a_remove_sysfs(struct device *dev) | 560 | void gk20a_remove_sysfs(struct device *dev) |
524 | { | 561 | { |
525 | struct gk20a *g = get_gk20a(to_platform_device(dev)); | 562 | struct gk20a *g = get_gk20a(to_platform_device(dev)); |
@@ -540,6 +577,7 @@ void gk20a_remove_sysfs(struct device *dev) | |||
540 | device_remove_file(dev, &dev_attr_aelpg_param); | 577 | device_remove_file(dev, &dev_attr_aelpg_param); |
541 | device_remove_file(dev, &dev_attr_aelpg_enable); | 578 | device_remove_file(dev, &dev_attr_aelpg_enable); |
542 | device_remove_file(dev, &dev_attr_allow_all); | 579 | device_remove_file(dev, &dev_attr_allow_all); |
580 | device_remove_file(dev, &dev_attr_tpc_fs_mask); | ||
543 | 581 | ||
544 | if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) | 582 | if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) |
545 | sysfs_remove_link(&dev->kobj, dev_name(dev)); | 583 | sysfs_remove_link(&dev->kobj, dev_name(dev)); |
@@ -566,6 +604,7 @@ void gk20a_create_sysfs(struct platform_device *dev) | |||
566 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_param); | 604 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_param); |
567 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_enable); | 605 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_enable); |
568 | error |= device_create_file(&dev->dev, &dev_attr_allow_all); | 606 | error |= device_create_file(&dev->dev, &dev_attr_allow_all); |
607 | error |= device_create_file(&dev->dev, &dev_attr_tpc_fs_mask); | ||
569 | 608 | ||
570 | if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev)) | 609 | if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev)) |
571 | error |= sysfs_create_link(&g->host1x_dev->dev.kobj, | 610 | error |= sysfs_create_link(&g->host1x_dev->dev.kobj, |
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 25d03736..72500b0e 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "hw_fb_gm20b.h" | 23 | #include "hw_fb_gm20b.h" |
24 | #include "hw_proj_gm20b.h" | 24 | #include "hw_proj_gm20b.h" |
25 | #include "hw_ctxsw_prog_gm20b.h" | 25 | #include "hw_ctxsw_prog_gm20b.h" |
26 | #include "hw_fuse_gm20b.h" | ||
26 | 27 | ||
27 | static void gr_gm20b_init_gpc_mmu(struct gk20a *g) | 28 | static void gr_gm20b_init_gpc_mmu(struct gk20a *g) |
28 | { | 29 | { |
@@ -478,6 +479,17 @@ static void gr_gm20b_get_sm_dsm_perf_ctrl_regs(struct gk20a *g, | |||
478 | *ctrl_register_stride = ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(); | 479 | *ctrl_register_stride = ctxsw_prog_extended_sm_dsm_perf_counter_control_register_stride_v(); |
479 | } | 480 | } |
480 | 481 | ||
482 | static u32 gr_gm20b_get_gpc_tpc_mask(struct gk20a *g, u32 gpc_index) | ||
483 | { | ||
484 | u32 val; | ||
485 | struct gr_gk20a *gr = &g->gr; | ||
486 | |||
487 | /* Toggle the bits of NV_FUSE_STATUS_OPT_TPC_GPC */ | ||
488 | val = gk20a_readl(g, fuse_status_opt_tpc_gpc_r(gpc_index)); | ||
489 | |||
490 | return (~val) & ((0x1 << gr->max_tpc_per_gpc_count) - 1); | ||
491 | } | ||
492 | |||
481 | static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) | 493 | static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) |
482 | { | 494 | { |
483 | struct gr_gk20a *gr = &g->gr; | 495 | struct gr_gk20a *gr = &g->gr; |
@@ -486,6 +498,7 @@ static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) | |||
486 | u32 sm_id = 0, gpc_id = 0; | 498 | u32 sm_id = 0, gpc_id = 0; |
487 | u32 sm_id_to_gpc_id[proj_scal_max_gpcs_v() * proj_scal_max_tpc_per_gpc_v()]; | 499 | u32 sm_id_to_gpc_id[proj_scal_max_gpcs_v() * proj_scal_max_tpc_per_gpc_v()]; |
488 | u32 tpc_per_gpc; | 500 | u32 tpc_per_gpc; |
501 | u32 tpc_fs_mask = 0, tpc_sm_id, gpc_tpc_id; | ||
489 | 502 | ||
490 | gk20a_dbg_fn(""); | 503 | gk20a_dbg_fn(""); |
491 | 504 | ||
@@ -556,22 +569,26 @@ static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) | |||
556 | gk20a_readl(g, gr_be0_crop_debug3_r()) | | 569 | gk20a_readl(g, gr_be0_crop_debug3_r()) | |
557 | gr_bes_crop_debug3_comp_vdc_4to2_disable_m()); | 570 | gr_bes_crop_debug3_comp_vdc_4to2_disable_m()); |
558 | 571 | ||
559 | if (tegra_platform_is_silicon()) { | 572 | for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) { |
560 | gk20a_writel(g, gr_fe_tpc_fs_r(), gr->pes_tpc_mask[0][0]); | 573 | tpc_fs_mask |= gr->gpc_tpc_mask[gpc_index] << |
561 | 574 | (gr->max_tpc_per_gpc_count * gpc_index); | |
562 | gk20a_writel(g, gr_cwd_gpc_tpc_id_r(0), gr_cwd_gpc_tpc_id_tpc0_f(0) | | 575 | } |
563 | gr_cwd_gpc_tpc_id_tpc1_f(1)); | 576 | gk20a_writel(g, gr_fe_tpc_fs_r(), tpc_fs_mask); |
564 | |||
565 | gk20a_writel(g, gr_cwd_sm_id_r(0), gr_cwd_sm_id_tpc0_f(0) | | ||
566 | gr_cwd_sm_id_tpc1_f(1)); | ||
567 | } else { | ||
568 | gk20a_writel(g, gr_fe_tpc_fs_r(), 1); | ||
569 | |||
570 | gk20a_writel(g, gr_cwd_gpc_tpc_id_r(0), gr_cwd_gpc_tpc_id_tpc0_f(0)); | ||
571 | |||
572 | gk20a_writel(g, gr_cwd_sm_id_r(0), gr_cwd_sm_id_tpc0_f(0)); | ||
573 | 577 | ||
578 | if (tpc_fs_mask & (0x1 << 0)) { | ||
579 | tpc_sm_id |= gr_cwd_sm_id_tpc0_f(0); | ||
580 | gpc_tpc_id |= gr_cwd_gpc_tpc_id_tpc0_f(0); | ||
581 | } | ||
582 | if (tpc_fs_mask & (0x1 << 1)) { | ||
583 | gpc_tpc_id |= gr_cwd_gpc_tpc_id_tpc1_f(1); | ||
584 | tpc_sm_id |= gr_cwd_sm_id_tpc1_f(1); | ||
574 | } | 585 | } |
586 | /* Each NV_PGRAPH_PRI_CWD_GPC_TPC_ID can store 4 TPCs. | ||
587 | * Since we know TPC number is less than 5. We select | ||
588 | * index 0 directly. */ | ||
589 | gk20a_writel(g, gr_cwd_gpc_tpc_id_r(0), gpc_tpc_id); | ||
590 | |||
591 | gk20a_writel(g, gr_cwd_sm_id_r(0), tpc_sm_id); | ||
575 | 592 | ||
576 | return 0; | 593 | return 0; |
577 | } | 594 | } |
@@ -733,4 +750,5 @@ void gm20b_init_gr(struct gpu_ops *gops) | |||
733 | #else | 750 | #else |
734 | gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; | 751 | gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; |
735 | #endif | 752 | #endif |
753 | gops->gr.get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask; | ||
736 | } | 754 | } |