diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b/gr_gv11b.c')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c index 033d83d5..8514cc1e 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "gv11b/gr_gv11b.h" | 44 | #include "gv11b/gr_gv11b.h" |
45 | #include "gv11b/mm_gv11b.h" | 45 | #include "gv11b/mm_gv11b.h" |
46 | #include "gv11b/subctx_gv11b.h" | 46 | #include "gv11b/subctx_gv11b.h" |
47 | #include "gv11b/gv11b.h" | ||
47 | 48 | ||
48 | #include <nvgpu/hw/gv11b/hw_gr_gv11b.h> | 49 | #include <nvgpu/hw/gv11b/hw_gr_gv11b.h> |
49 | #include <nvgpu/hw/gv11b/hw_fifo_gv11b.h> | 50 | #include <nvgpu/hw/gv11b/hw_fifo_gv11b.h> |
@@ -57,6 +58,10 @@ | |||
57 | 58 | ||
58 | #define GFXP_WFI_TIMEOUT_COUNT_IN_USEC_DEFAULT 1000 | 59 | #define GFXP_WFI_TIMEOUT_COUNT_IN_USEC_DEFAULT 1000 |
59 | 60 | ||
61 | /* ecc scrubbing will done in 1 pri read cycle,but for safety used 10 retries */ | ||
62 | #define ECC_SCRUBBING_TIMEOUT_MAX 1000 | ||
63 | #define ECC_SCRUBBING_TIMEOUT_DEFAULT 10 | ||
64 | |||
60 | bool gr_gv11b_is_valid_class(struct gk20a *g, u32 class_num) | 65 | bool gr_gv11b_is_valid_class(struct gk20a *g, u32 class_num) |
61 | { | 66 | { |
62 | bool valid = false; | 67 | bool valid = false; |
@@ -3674,3 +3679,183 @@ unsigned long gr_gv11b_get_max_gfxp_wfi_timeout_count(struct gk20a *g) | |||
3674 | /* 100 msec in usec count */ | 3679 | /* 100 msec in usec count */ |
3675 | return (100 * 1000UL); | 3680 | return (100 * 1000UL); |
3676 | } | 3681 | } |
3682 | |||
3683 | static int gr_gv11b_ecc_scrub_is_done(struct gk20a *g, | ||
3684 | u32 scrub_reg, u32 scrub_mask, u32 scrub_done) | ||
3685 | { | ||
3686 | struct nvgpu_timeout timeout; | ||
3687 | int status = 0; | ||
3688 | u32 val; | ||
3689 | |||
3690 | nvgpu_timeout_init(g, &timeout, | ||
3691 | ECC_SCRUBBING_TIMEOUT_MAX / | ||
3692 | ECC_SCRUBBING_TIMEOUT_DEFAULT, | ||
3693 | NVGPU_TIMER_RETRY_TIMER); | ||
3694 | do { | ||
3695 | val = gk20a_readl(g, scrub_reg); | ||
3696 | if ((val & scrub_mask) == scrub_done) | ||
3697 | goto exit; | ||
3698 | nvgpu_udelay(ECC_SCRUBBING_TIMEOUT_DEFAULT); | ||
3699 | } while (!nvgpu_timeout_expired(&timeout)); | ||
3700 | |||
3701 | if (nvgpu_timeout_peek_expired(&timeout)) | ||
3702 | status = -ETIMEDOUT; | ||
3703 | exit: | ||
3704 | return status; | ||
3705 | |||
3706 | } | ||
3707 | |||
3708 | static int gr_gv11b_ecc_scrub_sm_lrf(struct gk20a *g) | ||
3709 | { | ||
3710 | u32 scrub_mask, scrub_done; | ||
3711 | |||
3712 | if (!nvgpu_is_enabled(g, NVGPU_ECC_ENABLED_SM_LRF)) { | ||
3713 | nvgpu_log_info(g, "ECC SM LRF is disabled"); | ||
3714 | return 0; | ||
3715 | } | ||
3716 | |||
3717 | nvgpu_log_info(g, "gr_gv11b_ecc_scrub_sm_lrf"); | ||
3718 | scrub_mask = | ||
3719 | (gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp0_task_f() | | ||
3720 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp1_task_f() | | ||
3721 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp2_task_f() | | ||
3722 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp3_task_f() | | ||
3723 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp4_task_f() | | ||
3724 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp5_task_f() | | ||
3725 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp6_task_f() | | ||
3726 | gr_pri_gpcs_tpcs_sm_lrf_ecc_control_scrub_qrfdp7_task_f()); | ||
3727 | |||
3728 | /* Issue scrub lrf regions with single write command */ | ||
3729 | gk20a_writel(g, gr_pri_gpcs_tpcs_sm_lrf_ecc_control_r(), scrub_mask); | ||
3730 | |||
3731 | scrub_done = | ||
3732 | (gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp0_init_f() | | ||
3733 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp1_init_f() | | ||
3734 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp2_init_f() | | ||
3735 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp3_init_f() | | ||
3736 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp4_init_f() | | ||
3737 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp5_init_f() | | ||
3738 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp6_init_f() | | ||
3739 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_scrub_qrfdp7_init_f()); | ||
3740 | |||
3741 | return gr_gv11b_ecc_scrub_is_done(g, | ||
3742 | gr_pri_gpc0_tpc0_sm_lrf_ecc_control_r(), | ||
3743 | scrub_mask, scrub_done); | ||
3744 | } | ||
3745 | |||
3746 | static int gr_gv11b_ecc_scrub_sm_l1_data(struct gk20a *g) | ||
3747 | { | ||
3748 | u32 scrub_mask, scrub_done; | ||
3749 | |||
3750 | if (!nvgpu_is_enabled(g, NVGPU_ECC_ENABLED_SM_L1_DATA)) { | ||
3751 | nvgpu_log_info(g, "ECC L1DATA is disabled"); | ||
3752 | return 0; | ||
3753 | } | ||
3754 | nvgpu_log_info(g, "gr_gv11b_ecc_scrub_sm_l1_data"); | ||
3755 | scrub_mask = | ||
3756 | (gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_0_task_f() | | ||
3757 | gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_scrub_el1_1_task_f()); | ||
3758 | |||
3759 | gk20a_writel(g, gr_pri_gpcs_tpcs_sm_l1_data_ecc_control_r(), | ||
3760 | scrub_mask); | ||
3761 | |||
3762 | scrub_done = | ||
3763 | (gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_0_init_f() | | ||
3764 | gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_scrub_el1_1_init_f()); | ||
3765 | return gr_gv11b_ecc_scrub_is_done(g, | ||
3766 | gr_pri_gpc0_tpc0_sm_l1_data_ecc_control_r(), | ||
3767 | scrub_mask, scrub_done); | ||
3768 | } | ||
3769 | |||
3770 | static int gr_gv11b_ecc_scrub_sm_l1_tag(struct gk20a *g) | ||
3771 | { | ||
3772 | u32 scrub_mask, scrub_done; | ||
3773 | |||
3774 | if (!nvgpu_is_enabled(g, NVGPU_ECC_ENABLED_SM_L1_TAG)) { | ||
3775 | nvgpu_log_info(g, "ECC L1TAG is disabled"); | ||
3776 | return 0; | ||
3777 | } | ||
3778 | nvgpu_log_info(g, "gr_gv11b_ecc_scrub_sm_l1_tag"); | ||
3779 | scrub_mask = | ||
3780 | (gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_0_task_f() | | ||
3781 | gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_scrub_el1_1_task_f()); | ||
3782 | gk20a_writel(g, gr_pri_gpcs_tpcs_sm_l1_tag_ecc_control_r(), scrub_mask); | ||
3783 | |||
3784 | scrub_done = | ||
3785 | (gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_0_init_f() | | ||
3786 | gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_scrub_el1_1_init_f()); | ||
3787 | return gr_gv11b_ecc_scrub_is_done(g, | ||
3788 | gr_pri_gpc0_tpc0_sm_l1_tag_ecc_control_r(), | ||
3789 | scrub_mask, scrub_done); | ||
3790 | } | ||
3791 | |||
3792 | static int gr_gv11b_ecc_scrub_sm_cbu(struct gk20a *g) | ||
3793 | { | ||
3794 | u32 scrub_mask, scrub_done; | ||
3795 | |||
3796 | if (!nvgpu_is_enabled(g, NVGPU_ECC_ENABLED_SM_CBU)) { | ||
3797 | nvgpu_log_info(g, "ECC CBU is disabled"); | ||
3798 | return 0; | ||
3799 | } | ||
3800 | nvgpu_log_info(g, "gr_gv11b_ecc_scrub_sm_cbu"); | ||
3801 | scrub_mask = | ||
3802 | (gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm0_task_f() | | ||
3803 | gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_warp_sm1_task_f() | | ||
3804 | gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm0_task_f() | | ||
3805 | gr_pri_gpcs_tpcs_sm_cbu_ecc_control_scrub_barrier_sm1_task_f()); | ||
3806 | gk20a_writel(g, gr_pri_gpcs_tpcs_sm_cbu_ecc_control_r(), scrub_mask); | ||
3807 | |||
3808 | scrub_done = | ||
3809 | (gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm0_init_f() | | ||
3810 | gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_warp_sm1_init_f() | | ||
3811 | gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm0_init_f() | | ||
3812 | gr_pri_gpc0_tpc0_sm_cbu_ecc_control_scrub_barrier_sm1_init_f()); | ||
3813 | return gr_gv11b_ecc_scrub_is_done(g, | ||
3814 | gr_pri_gpc0_tpc0_sm_cbu_ecc_control_r(), | ||
3815 | scrub_mask, scrub_done); | ||
3816 | } | ||
3817 | |||
3818 | static int gr_gv11b_ecc_scrub_sm_icahe(struct gk20a *g) | ||
3819 | { | ||
3820 | u32 scrub_mask, scrub_done; | ||
3821 | |||
3822 | if (!nvgpu_is_enabled(g, NVGPU_ECC_ENABLED_SM_ICACHE)) { | ||
3823 | nvgpu_log_info(g, "ECC ICAHE is disabled"); | ||
3824 | return 0; | ||
3825 | } | ||
3826 | nvgpu_log_info(g, "gr_gv11b_ecc_scrub_sm_icahe"); | ||
3827 | scrub_mask = | ||
3828 | (gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_data_task_f() | | ||
3829 | gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l0_predecode_task_f() | | ||
3830 | gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_data_task_f() | | ||
3831 | gr_pri_gpcs_tpcs_sm_icache_ecc_control_scrub_l1_predecode_task_f()); | ||
3832 | gk20a_writel(g, gr_pri_gpcs_tpcs_sm_icache_ecc_control_r(), scrub_mask); | ||
3833 | |||
3834 | scrub_done = | ||
3835 | (gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_data_init_f() | | ||
3836 | gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l0_predecode_init_f() | | ||
3837 | gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_data_init_f() | | ||
3838 | gr_pri_gpc0_tpc0_sm_icache_ecc_control_scrub_l1_predecode_init_f()); | ||
3839 | return gr_gv11b_ecc_scrub_is_done(g, | ||
3840 | gr_pri_gpc0_tpc0_sm_icache_ecc_control_r(), | ||
3841 | scrub_mask, scrub_done); | ||
3842 | } | ||
3843 | |||
3844 | void gr_gv11b_ecc_init_scrub_reg(struct gk20a *g) | ||
3845 | { | ||
3846 | nvgpu_log_fn(g, "ecc srub start "); | ||
3847 | |||
3848 | gv11b_detect_ecc_enabled_units(g); | ||
3849 | |||
3850 | if (gr_gv11b_ecc_scrub_sm_lrf(g)) | ||
3851 | nvgpu_warn(g, "ECC SCRUB SM LRF Failed"); | ||
3852 | if (gr_gv11b_ecc_scrub_sm_l1_data(g)) | ||
3853 | nvgpu_warn(g, "ECC SCRUB SM L1 DATA Failed"); | ||
3854 | if (gr_gv11b_ecc_scrub_sm_l1_tag(g)) | ||
3855 | nvgpu_warn(g, "ECC SCRUB SM L1 TAG Failed"); | ||
3856 | if (gr_gv11b_ecc_scrub_sm_cbu(g)) | ||
3857 | nvgpu_warn(g, "ECC SCRUB SM CBU Failed"); | ||
3858 | if (gr_gv11b_ecc_scrub_sm_icahe(g)) | ||
3859 | nvgpu_warn(g, "ECC SCRUB SM ICACHE Failed"); | ||
3860 | |||
3861 | } | ||