114f43e8fSLeo Liu /*
214f43e8fSLeo Liu * Copyright 2019 Advanced Micro Devices, Inc.
314f43e8fSLeo Liu *
414f43e8fSLeo Liu * Permission is hereby granted, free of charge, to any person obtaining a
514f43e8fSLeo Liu * copy of this software and associated documentation files (the "Software"),
614f43e8fSLeo Liu * to deal in the Software without restriction, including without limitation
714f43e8fSLeo Liu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
814f43e8fSLeo Liu * and/or sell copies of the Software, and to permit persons to whom the
914f43e8fSLeo Liu * Software is furnished to do so, subject to the following conditions:
1014f43e8fSLeo Liu *
1114f43e8fSLeo Liu * The above copyright notice and this permission notice shall be included in
1214f43e8fSLeo Liu * all copies or substantial portions of the Software.
1314f43e8fSLeo Liu *
1414f43e8fSLeo Liu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1514f43e8fSLeo Liu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1614f43e8fSLeo Liu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1714f43e8fSLeo Liu * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1814f43e8fSLeo Liu * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1914f43e8fSLeo Liu * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2014f43e8fSLeo Liu * OTHER DEALINGS IN THE SOFTWARE.
2114f43e8fSLeo Liu *
2214f43e8fSLeo Liu */
2314f43e8fSLeo Liu
2414f43e8fSLeo Liu #include "amdgpu.h"
2514f43e8fSLeo Liu #include "amdgpu_jpeg.h"
2614f43e8fSLeo Liu #include "soc15.h"
2714f43e8fSLeo Liu #include "soc15d.h"
2814f43e8fSLeo Liu #include "jpeg_v2_0.h"
29749831acSMohammad Zafar Ziya #include "jpeg_v2_5.h"
3014f43e8fSLeo Liu
3114f43e8fSLeo Liu #include "vcn/vcn_2_5_offset.h"
3214f43e8fSLeo Liu #include "vcn/vcn_2_5_sh_mask.h"
3314f43e8fSLeo Liu #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
3414f43e8fSLeo Liu
3514f43e8fSLeo Liu #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
3614f43e8fSLeo Liu
3714f43e8fSLeo Liu #define JPEG25_MAX_HW_INSTANCES_ARCTURUS 2
3814f43e8fSLeo Liu
3914f43e8fSLeo Liu static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
4014f43e8fSLeo Liu static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev);
4114f43e8fSLeo Liu static int jpeg_v2_5_set_powergating_state(void *handle,
4214f43e8fSLeo Liu enum amd_powergating_state state);
43749831acSMohammad Zafar Ziya static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev);
4414f43e8fSLeo Liu
4514f43e8fSLeo Liu static int amdgpu_ih_clientid_jpeg[] = {
4614f43e8fSLeo Liu SOC15_IH_CLIENTID_VCN,
4714f43e8fSLeo Liu SOC15_IH_CLIENTID_VCN1
4814f43e8fSLeo Liu };
4914f43e8fSLeo Liu
5014f43e8fSLeo Liu /**
5114f43e8fSLeo Liu * jpeg_v2_5_early_init - set function pointers
5214f43e8fSLeo Liu *
5314f43e8fSLeo Liu * @handle: amdgpu_device pointer
5414f43e8fSLeo Liu *
5514f43e8fSLeo Liu * Set ring and irq function pointers
5614f43e8fSLeo Liu */
jpeg_v2_5_early_init(void * handle)5714f43e8fSLeo Liu static int jpeg_v2_5_early_init(void *handle)
5814f43e8fSLeo Liu {
5914f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
6014f43e8fSLeo Liu u32 harvest;
6114f43e8fSLeo Liu int i;
6214f43e8fSLeo Liu
6328bb7f13SJames Zhu adev->jpeg.num_jpeg_rings = 1;
6414f43e8fSLeo Liu adev->jpeg.num_jpeg_inst = JPEG25_MAX_HW_INSTANCES_ARCTURUS;
6514f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
6614f43e8fSLeo Liu harvest = RREG32_SOC15(JPEG, i, mmCC_UVD_HARVESTING);
6714f43e8fSLeo Liu if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
6814f43e8fSLeo Liu adev->jpeg.harvest_config |= 1 << i;
6914f43e8fSLeo Liu }
7014f43e8fSLeo Liu if (adev->jpeg.harvest_config == (AMDGPU_JPEG_HARVEST_JPEG0 |
7114f43e8fSLeo Liu AMDGPU_JPEG_HARVEST_JPEG1))
7214f43e8fSLeo Liu return -ENOENT;
7314f43e8fSLeo Liu
7414f43e8fSLeo Liu jpeg_v2_5_set_dec_ring_funcs(adev);
7514f43e8fSLeo Liu jpeg_v2_5_set_irq_funcs(adev);
76749831acSMohammad Zafar Ziya jpeg_v2_5_set_ras_funcs(adev);
7714f43e8fSLeo Liu
7814f43e8fSLeo Liu return 0;
7914f43e8fSLeo Liu }
8014f43e8fSLeo Liu
8114f43e8fSLeo Liu /**
8214f43e8fSLeo Liu * jpeg_v2_5_sw_init - sw init for JPEG block
8314f43e8fSLeo Liu *
8414f43e8fSLeo Liu * @handle: amdgpu_device pointer
8514f43e8fSLeo Liu *
8614f43e8fSLeo Liu * Load firmware and sw initialization
8714f43e8fSLeo Liu */
jpeg_v2_5_sw_init(void * handle)8814f43e8fSLeo Liu static int jpeg_v2_5_sw_init(void *handle)
8914f43e8fSLeo Liu {
9014f43e8fSLeo Liu struct amdgpu_ring *ring;
9114f43e8fSLeo Liu int i, r;
9214f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
9314f43e8fSLeo Liu
9414f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
9514f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
9614f43e8fSLeo Liu continue;
9714f43e8fSLeo Liu
9814f43e8fSLeo Liu /* JPEG TRAP */
9914f43e8fSLeo Liu r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
10014f43e8fSLeo Liu VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
10114f43e8fSLeo Liu if (r)
10214f43e8fSLeo Liu return r;
1037e0357fcSMohammad Zafar Ziya
1047e0357fcSMohammad Zafar Ziya /* JPEG DJPEG POISON EVENT */
1057e0357fcSMohammad Zafar Ziya r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
106674f90f8SHoratio Zhang VCN_2_6__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);
1077e0357fcSMohammad Zafar Ziya if (r)
1087e0357fcSMohammad Zafar Ziya return r;
1097e0357fcSMohammad Zafar Ziya
1107e0357fcSMohammad Zafar Ziya /* JPEG EJPEG POISON EVENT */
1117e0357fcSMohammad Zafar Ziya r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
112674f90f8SHoratio Zhang VCN_2_6__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);
1137e0357fcSMohammad Zafar Ziya if (r)
1147e0357fcSMohammad Zafar Ziya return r;
11514f43e8fSLeo Liu }
11614f43e8fSLeo Liu
11714f43e8fSLeo Liu r = amdgpu_jpeg_sw_init(adev);
11814f43e8fSLeo Liu if (r)
11914f43e8fSLeo Liu return r;
12014f43e8fSLeo Liu
12114f43e8fSLeo Liu r = amdgpu_jpeg_resume(adev);
12214f43e8fSLeo Liu if (r)
12314f43e8fSLeo Liu return r;
12414f43e8fSLeo Liu
12514f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
12614f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
12714f43e8fSLeo Liu continue;
12814f43e8fSLeo Liu
129bc224553SJames Zhu ring = adev->jpeg.inst[i].ring_dec;
13014f43e8fSLeo Liu ring->use_doorbell = true;
1314e8303cfSLijo Lazar if (amdgpu_ip_version(adev, UVD_HWIP, 0) == IP_VERSION(2, 5, 0))
132f4caf584SHawking Zhang ring->vm_hub = AMDGPU_MMHUB1(0);
1330530553bSLe Ma else
134f4caf584SHawking Zhang ring->vm_hub = AMDGPU_MMHUB0(0);
13514f43e8fSLeo Liu ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
13614f43e8fSLeo Liu sprintf(ring->name, "jpeg_dec_%d", i);
1371c6d567bSNirmoy Das r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
138c107171bSChristian König 0, AMDGPU_RING_PRIO_DEFAULT, NULL);
13914f43e8fSLeo Liu if (r)
14014f43e8fSLeo Liu return r;
14114f43e8fSLeo Liu
142bc224553SJames Zhu adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
143bc224553SJames Zhu adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_PITCH);
14414f43e8fSLeo Liu }
14514f43e8fSLeo Liu
1465640e06eSHawking Zhang r = amdgpu_jpeg_ras_sw_init(adev);
1475640e06eSHawking Zhang if (r)
1485640e06eSHawking Zhang return r;
1495640e06eSHawking Zhang
15014f43e8fSLeo Liu return 0;
15114f43e8fSLeo Liu }
15214f43e8fSLeo Liu
15314f43e8fSLeo Liu /**
15414f43e8fSLeo Liu * jpeg_v2_5_sw_fini - sw fini for JPEG block
15514f43e8fSLeo Liu *
15614f43e8fSLeo Liu * @handle: amdgpu_device pointer
15714f43e8fSLeo Liu *
15814f43e8fSLeo Liu * JPEG suspend and free up sw allocation
15914f43e8fSLeo Liu */
jpeg_v2_5_sw_fini(void * handle)16014f43e8fSLeo Liu static int jpeg_v2_5_sw_fini(void *handle)
16114f43e8fSLeo Liu {
16214f43e8fSLeo Liu int r;
16314f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
16414f43e8fSLeo Liu
16514f43e8fSLeo Liu r = amdgpu_jpeg_suspend(adev);
16614f43e8fSLeo Liu if (r)
16714f43e8fSLeo Liu return r;
16814f43e8fSLeo Liu
16914f43e8fSLeo Liu r = amdgpu_jpeg_sw_fini(adev);
17014f43e8fSLeo Liu
17114f43e8fSLeo Liu return r;
17214f43e8fSLeo Liu }
17314f43e8fSLeo Liu
17414f43e8fSLeo Liu /**
17514f43e8fSLeo Liu * jpeg_v2_5_hw_init - start and test JPEG block
17614f43e8fSLeo Liu *
17714f43e8fSLeo Liu * @handle: amdgpu_device pointer
17814f43e8fSLeo Liu *
17914f43e8fSLeo Liu */
jpeg_v2_5_hw_init(void * handle)18014f43e8fSLeo Liu static int jpeg_v2_5_hw_init(void *handle)
18114f43e8fSLeo Liu {
18214f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
18314f43e8fSLeo Liu struct amdgpu_ring *ring;
18414f43e8fSLeo Liu int i, r;
18514f43e8fSLeo Liu
18614f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
18714f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
18814f43e8fSLeo Liu continue;
18914f43e8fSLeo Liu
190bc224553SJames Zhu ring = adev->jpeg.inst[i].ring_dec;
19114f43e8fSLeo Liu adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
19214f43e8fSLeo Liu (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
19314f43e8fSLeo Liu
19414f43e8fSLeo Liu r = amdgpu_ring_test_helper(ring);
19514f43e8fSLeo Liu if (r)
19614f43e8fSLeo Liu return r;
19714f43e8fSLeo Liu }
19814f43e8fSLeo Liu
19914f43e8fSLeo Liu return 0;
20014f43e8fSLeo Liu }
20114f43e8fSLeo Liu
20214f43e8fSLeo Liu /**
20314f43e8fSLeo Liu * jpeg_v2_5_hw_fini - stop the hardware block
20414f43e8fSLeo Liu *
20514f43e8fSLeo Liu * @handle: amdgpu_device pointer
20614f43e8fSLeo Liu *
20714f43e8fSLeo Liu * Stop the JPEG block, mark ring as not ready any more
20814f43e8fSLeo Liu */
jpeg_v2_5_hw_fini(void * handle)20914f43e8fSLeo Liu static int jpeg_v2_5_hw_fini(void *handle)
21014f43e8fSLeo Liu {
21114f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
21214f43e8fSLeo Liu int i;
21314f43e8fSLeo Liu
21423f10a57SJames Zhu cancel_delayed_work_sync(&adev->vcn.idle_work);
21523f10a57SJames Zhu
21614f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
21714f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
21814f43e8fSLeo Liu continue;
21914f43e8fSLeo Liu
22014f43e8fSLeo Liu if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
22114f43e8fSLeo Liu RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS))
22214f43e8fSLeo Liu jpeg_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
223674f90f8SHoratio Zhang
224674f90f8SHoratio Zhang if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG))
225674f90f8SHoratio Zhang amdgpu_irq_put(adev, &adev->jpeg.inst[i].ras_poison_irq, 0);
22614f43e8fSLeo Liu }
22714f43e8fSLeo Liu
22814f43e8fSLeo Liu return 0;
22914f43e8fSLeo Liu }
23014f43e8fSLeo Liu
23114f43e8fSLeo Liu /**
23214f43e8fSLeo Liu * jpeg_v2_5_suspend - suspend JPEG block
23314f43e8fSLeo Liu *
23414f43e8fSLeo Liu * @handle: amdgpu_device pointer
23514f43e8fSLeo Liu *
23614f43e8fSLeo Liu * HW fini and suspend JPEG block
23714f43e8fSLeo Liu */
jpeg_v2_5_suspend(void * handle)23814f43e8fSLeo Liu static int jpeg_v2_5_suspend(void *handle)
23914f43e8fSLeo Liu {
24014f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
24114f43e8fSLeo Liu int r;
24214f43e8fSLeo Liu
24314f43e8fSLeo Liu r = jpeg_v2_5_hw_fini(adev);
24414f43e8fSLeo Liu if (r)
24514f43e8fSLeo Liu return r;
24614f43e8fSLeo Liu
24714f43e8fSLeo Liu r = amdgpu_jpeg_suspend(adev);
24814f43e8fSLeo Liu
24914f43e8fSLeo Liu return r;
25014f43e8fSLeo Liu }
25114f43e8fSLeo Liu
25214f43e8fSLeo Liu /**
25314f43e8fSLeo Liu * jpeg_v2_5_resume - resume JPEG block
25414f43e8fSLeo Liu *
25514f43e8fSLeo Liu * @handle: amdgpu_device pointer
25614f43e8fSLeo Liu *
25714f43e8fSLeo Liu * Resume firmware and hw init JPEG block
25814f43e8fSLeo Liu */
jpeg_v2_5_resume(void * handle)25914f43e8fSLeo Liu static int jpeg_v2_5_resume(void *handle)
26014f43e8fSLeo Liu {
26114f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
26214f43e8fSLeo Liu int r;
26314f43e8fSLeo Liu
26414f43e8fSLeo Liu r = amdgpu_jpeg_resume(adev);
26514f43e8fSLeo Liu if (r)
26614f43e8fSLeo Liu return r;
26714f43e8fSLeo Liu
26814f43e8fSLeo Liu r = jpeg_v2_5_hw_init(adev);
26914f43e8fSLeo Liu
27014f43e8fSLeo Liu return r;
27114f43e8fSLeo Liu }
27214f43e8fSLeo Liu
jpeg_v2_5_disable_clock_gating(struct amdgpu_device * adev,int inst)27314f43e8fSLeo Liu static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
27414f43e8fSLeo Liu {
27514f43e8fSLeo Liu uint32_t data;
27614f43e8fSLeo Liu
27714f43e8fSLeo Liu data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);
27814f43e8fSLeo Liu if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
27914f43e8fSLeo Liu data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
28014f43e8fSLeo Liu else
28114f43e8fSLeo Liu data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
28214f43e8fSLeo Liu
28314f43e8fSLeo Liu data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
28414f43e8fSLeo Liu data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
28514f43e8fSLeo Liu WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);
28614f43e8fSLeo Liu
28714f43e8fSLeo Liu data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);
28814f43e8fSLeo Liu data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
28914f43e8fSLeo Liu | JPEG_CGC_GATE__JPEG2_DEC_MASK
29014f43e8fSLeo Liu | JPEG_CGC_GATE__JMCIF_MASK
29114f43e8fSLeo Liu | JPEG_CGC_GATE__JRBBM_MASK);
29214f43e8fSLeo Liu WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);
29314f43e8fSLeo Liu
29414f43e8fSLeo Liu data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);
29514f43e8fSLeo Liu data &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK
29614f43e8fSLeo Liu | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK
29714f43e8fSLeo Liu | JPEG_CGC_CTRL__JMCIF_MODE_MASK
29814f43e8fSLeo Liu | JPEG_CGC_CTRL__JRBBM_MODE_MASK);
29914f43e8fSLeo Liu WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);
30014f43e8fSLeo Liu }
30114f43e8fSLeo Liu
jpeg_v2_5_enable_clock_gating(struct amdgpu_device * adev,int inst)30214f43e8fSLeo Liu static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
30314f43e8fSLeo Liu {
30414f43e8fSLeo Liu uint32_t data;
30514f43e8fSLeo Liu
30614f43e8fSLeo Liu data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);
30714f43e8fSLeo Liu data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
30814f43e8fSLeo Liu |JPEG_CGC_GATE__JPEG2_DEC_MASK
30914f43e8fSLeo Liu |JPEG_CGC_GATE__JPEG_ENC_MASK
31014f43e8fSLeo Liu |JPEG_CGC_GATE__JMCIF_MASK
31114f43e8fSLeo Liu |JPEG_CGC_GATE__JRBBM_MASK);
31214f43e8fSLeo Liu WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);
31314f43e8fSLeo Liu }
31414f43e8fSLeo Liu
31514f43e8fSLeo Liu /**
31614f43e8fSLeo Liu * jpeg_v2_5_start - start JPEG block
31714f43e8fSLeo Liu *
31814f43e8fSLeo Liu * @adev: amdgpu_device pointer
31914f43e8fSLeo Liu *
32014f43e8fSLeo Liu * Setup and start the JPEG block
32114f43e8fSLeo Liu */
jpeg_v2_5_start(struct amdgpu_device * adev)32214f43e8fSLeo Liu static int jpeg_v2_5_start(struct amdgpu_device *adev)
32314f43e8fSLeo Liu {
32414f43e8fSLeo Liu struct amdgpu_ring *ring;
32514f43e8fSLeo Liu int i;
32614f43e8fSLeo Liu
32714f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
32814f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
32914f43e8fSLeo Liu continue;
33014f43e8fSLeo Liu
331bc224553SJames Zhu ring = adev->jpeg.inst[i].ring_dec;
33214f43e8fSLeo Liu /* disable anti hang mechanism */
33314f43e8fSLeo Liu WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0,
33414f43e8fSLeo Liu ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
33514f43e8fSLeo Liu
33614f43e8fSLeo Liu /* JPEG disable CGC */
33714f43e8fSLeo Liu jpeg_v2_5_disable_clock_gating(adev, i);
33814f43e8fSLeo Liu
33914f43e8fSLeo Liu /* MJPEG global tiling registers */
34014f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
34114f43e8fSLeo Liu adev->gfx.config.gb_addr_config);
34214f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
34314f43e8fSLeo Liu adev->gfx.config.gb_addr_config);
34414f43e8fSLeo Liu
34514f43e8fSLeo Liu /* enable JMI channel */
34614f43e8fSLeo Liu WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0,
34714f43e8fSLeo Liu ~UVD_JMI_CNTL__SOFT_RESET_MASK);
34814f43e8fSLeo Liu
34914f43e8fSLeo Liu /* enable System Interrupt for JRBC */
35014f43e8fSLeo Liu WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN),
35114f43e8fSLeo Liu JPEG_SYS_INT_EN__DJRBC_MASK,
35214f43e8fSLeo Liu ~JPEG_SYS_INT_EN__DJRBC_MASK);
35314f43e8fSLeo Liu
35414f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0);
35514f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
35614f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
35714f43e8fSLeo Liu lower_32_bits(ring->gpu_addr));
35814f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
35914f43e8fSLeo Liu upper_32_bits(ring->gpu_addr));
36014f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0);
36114f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0);
36214f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
36314f43e8fSLeo Liu WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
36414f43e8fSLeo Liu ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR);
36514f43e8fSLeo Liu }
36614f43e8fSLeo Liu
36714f43e8fSLeo Liu return 0;
36814f43e8fSLeo Liu }
36914f43e8fSLeo Liu
37014f43e8fSLeo Liu /**
37114f43e8fSLeo Liu * jpeg_v2_5_stop - stop JPEG block
37214f43e8fSLeo Liu *
37314f43e8fSLeo Liu * @adev: amdgpu_device pointer
37414f43e8fSLeo Liu *
37514f43e8fSLeo Liu * stop the JPEG block
37614f43e8fSLeo Liu */
jpeg_v2_5_stop(struct amdgpu_device * adev)37714f43e8fSLeo Liu static int jpeg_v2_5_stop(struct amdgpu_device *adev)
37814f43e8fSLeo Liu {
37914f43e8fSLeo Liu int i;
38014f43e8fSLeo Liu
38114f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
38214f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
38314f43e8fSLeo Liu continue;
38414f43e8fSLeo Liu
38514f43e8fSLeo Liu /* reset JMI */
38614f43e8fSLeo Liu WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL),
38714f43e8fSLeo Liu UVD_JMI_CNTL__SOFT_RESET_MASK,
38814f43e8fSLeo Liu ~UVD_JMI_CNTL__SOFT_RESET_MASK);
38914f43e8fSLeo Liu
39014f43e8fSLeo Liu jpeg_v2_5_enable_clock_gating(adev, i);
39114f43e8fSLeo Liu
39214f43e8fSLeo Liu /* enable anti hang mechanism */
39314f43e8fSLeo Liu WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS),
39414f43e8fSLeo Liu UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
39514f43e8fSLeo Liu ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
39614f43e8fSLeo Liu }
39714f43e8fSLeo Liu
39814f43e8fSLeo Liu return 0;
39914f43e8fSLeo Liu }
40014f43e8fSLeo Liu
40114f43e8fSLeo Liu /**
40214f43e8fSLeo Liu * jpeg_v2_5_dec_ring_get_rptr - get read pointer
40314f43e8fSLeo Liu *
40414f43e8fSLeo Liu * @ring: amdgpu_ring pointer
40514f43e8fSLeo Liu *
40614f43e8fSLeo Liu * Returns the current hardware read pointer
40714f43e8fSLeo Liu */
jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring * ring)40814f43e8fSLeo Liu static uint64_t jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
40914f43e8fSLeo Liu {
41014f43e8fSLeo Liu struct amdgpu_device *adev = ring->adev;
41114f43e8fSLeo Liu
41214f43e8fSLeo Liu return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_RPTR);
41314f43e8fSLeo Liu }
41414f43e8fSLeo Liu
41514f43e8fSLeo Liu /**
41614f43e8fSLeo Liu * jpeg_v2_5_dec_ring_get_wptr - get write pointer
41714f43e8fSLeo Liu *
41814f43e8fSLeo Liu * @ring: amdgpu_ring pointer
41914f43e8fSLeo Liu *
42014f43e8fSLeo Liu * Returns the current hardware write pointer
42114f43e8fSLeo Liu */
jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring * ring)42214f43e8fSLeo Liu static uint64_t jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
42314f43e8fSLeo Liu {
42414f43e8fSLeo Liu struct amdgpu_device *adev = ring->adev;
42514f43e8fSLeo Liu
42614f43e8fSLeo Liu if (ring->use_doorbell)
4273748424bSJack Xiao return *ring->wptr_cpu_addr;
42814f43e8fSLeo Liu else
42914f43e8fSLeo Liu return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR);
43014f43e8fSLeo Liu }
43114f43e8fSLeo Liu
43214f43e8fSLeo Liu /**
43314f43e8fSLeo Liu * jpeg_v2_5_dec_ring_set_wptr - set write pointer
43414f43e8fSLeo Liu *
43514f43e8fSLeo Liu * @ring: amdgpu_ring pointer
43614f43e8fSLeo Liu *
43714f43e8fSLeo Liu * Commits the write pointer to the hardware
43814f43e8fSLeo Liu */
jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring * ring)43914f43e8fSLeo Liu static void jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
44014f43e8fSLeo Liu {
44114f43e8fSLeo Liu struct amdgpu_device *adev = ring->adev;
44214f43e8fSLeo Liu
44314f43e8fSLeo Liu if (ring->use_doorbell) {
4443748424bSJack Xiao *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
44514f43e8fSLeo Liu WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
44614f43e8fSLeo Liu } else {
44714f43e8fSLeo Liu WREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
44814f43e8fSLeo Liu }
44914f43e8fSLeo Liu }
45014f43e8fSLeo Liu
451c6051149SJames Zhu /**
452c6051149SJames Zhu * jpeg_v2_6_dec_ring_insert_start - insert a start command
453c6051149SJames Zhu *
454c6051149SJames Zhu * @ring: amdgpu_ring pointer
455c6051149SJames Zhu *
456c6051149SJames Zhu * Write a start command to the ring.
457c6051149SJames Zhu */
jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring * ring)458c6051149SJames Zhu static void jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring *ring)
459c6051149SJames Zhu {
460c6051149SJames Zhu amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
461c6051149SJames Zhu 0, 0, PACKETJ_TYPE0));
462c6051149SJames Zhu amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
463c6051149SJames Zhu
464c6051149SJames Zhu amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
465c6051149SJames Zhu 0, 0, PACKETJ_TYPE0));
466c6051149SJames Zhu amdgpu_ring_write(ring, 0x80000000 | (1 << (ring->me * 2 + 14)));
467c6051149SJames Zhu }
468c6051149SJames Zhu
469c6051149SJames Zhu /**
470c6051149SJames Zhu * jpeg_v2_6_dec_ring_insert_end - insert a end command
471c6051149SJames Zhu *
472c6051149SJames Zhu * @ring: amdgpu_ring pointer
473c6051149SJames Zhu *
474c6051149SJames Zhu * Write a end command to the ring.
475c6051149SJames Zhu */
jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring * ring)476c6051149SJames Zhu static void jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring *ring)
477c6051149SJames Zhu {
478c6051149SJames Zhu amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
479c6051149SJames Zhu 0, 0, PACKETJ_TYPE0));
480c6051149SJames Zhu amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
481c6051149SJames Zhu
482c6051149SJames Zhu amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
483c6051149SJames Zhu 0, 0, PACKETJ_TYPE0));
484c6051149SJames Zhu amdgpu_ring_write(ring, (1 << (ring->me * 2 + 14)));
485c6051149SJames Zhu }
486c6051149SJames Zhu
jpeg_v2_5_is_idle(void * handle)48714f43e8fSLeo Liu static bool jpeg_v2_5_is_idle(void *handle)
48814f43e8fSLeo Liu {
48914f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
49014f43e8fSLeo Liu int i, ret = 1;
49114f43e8fSLeo Liu
49214f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
49314f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
49414f43e8fSLeo Liu continue;
49514f43e8fSLeo Liu
49614f43e8fSLeo Liu ret &= (((RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS) &
49714f43e8fSLeo Liu UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
49814f43e8fSLeo Liu UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
49914f43e8fSLeo Liu }
50014f43e8fSLeo Liu
50114f43e8fSLeo Liu return ret;
50214f43e8fSLeo Liu }
50314f43e8fSLeo Liu
jpeg_v2_5_wait_for_idle(void * handle)50414f43e8fSLeo Liu static int jpeg_v2_5_wait_for_idle(void *handle)
50514f43e8fSLeo Liu {
50614f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
507450da2efSJames Zhu int i, ret;
50814f43e8fSLeo Liu
50914f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
51014f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
51114f43e8fSLeo Liu continue;
51214f43e8fSLeo Liu
513450da2efSJames Zhu ret = SOC15_WAIT_ON_RREG(JPEG, i, mmUVD_JRBC_STATUS,
51414f43e8fSLeo Liu UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
515450da2efSJames Zhu UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
51614f43e8fSLeo Liu if (ret)
51714f43e8fSLeo Liu return ret;
51814f43e8fSLeo Liu }
51914f43e8fSLeo Liu
52057f01856SColin Ian King return 0;
52114f43e8fSLeo Liu }
52214f43e8fSLeo Liu
jpeg_v2_5_set_clockgating_state(void * handle,enum amd_clockgating_state state)52314f43e8fSLeo Liu static int jpeg_v2_5_set_clockgating_state(void *handle,
52414f43e8fSLeo Liu enum amd_clockgating_state state)
52514f43e8fSLeo Liu {
52614f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
527a9d4fe2fSNirmoy Das bool enable = (state == AMD_CG_STATE_GATE);
52814f43e8fSLeo Liu int i;
52914f43e8fSLeo Liu
53014f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
53114f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
53214f43e8fSLeo Liu continue;
53314f43e8fSLeo Liu
53414f43e8fSLeo Liu if (enable) {
5356c1cb08eSJames Zhu if (!jpeg_v2_5_is_idle(handle))
53614f43e8fSLeo Liu return -EBUSY;
53714f43e8fSLeo Liu jpeg_v2_5_enable_clock_gating(adev, i);
53814f43e8fSLeo Liu } else {
53914f43e8fSLeo Liu jpeg_v2_5_disable_clock_gating(adev, i);
54014f43e8fSLeo Liu }
54114f43e8fSLeo Liu }
54214f43e8fSLeo Liu
54314f43e8fSLeo Liu return 0;
54414f43e8fSLeo Liu }
54514f43e8fSLeo Liu
jpeg_v2_5_set_powergating_state(void * handle,enum amd_powergating_state state)54614f43e8fSLeo Liu static int jpeg_v2_5_set_powergating_state(void *handle,
54714f43e8fSLeo Liu enum amd_powergating_state state)
54814f43e8fSLeo Liu {
54914f43e8fSLeo Liu struct amdgpu_device *adev = (struct amdgpu_device *)handle;
55014f43e8fSLeo Liu int ret;
55114f43e8fSLeo Liu
55214f43e8fSLeo Liu if (state == adev->jpeg.cur_state)
55314f43e8fSLeo Liu return 0;
55414f43e8fSLeo Liu
55514f43e8fSLeo Liu if (state == AMD_PG_STATE_GATE)
55614f43e8fSLeo Liu ret = jpeg_v2_5_stop(adev);
55714f43e8fSLeo Liu else
55814f43e8fSLeo Liu ret = jpeg_v2_5_start(adev);
55914f43e8fSLeo Liu
56014f43e8fSLeo Liu if (!ret)
56114f43e8fSLeo Liu adev->jpeg.cur_state = state;
56214f43e8fSLeo Liu
56314f43e8fSLeo Liu return ret;
56414f43e8fSLeo Liu }
56514f43e8fSLeo Liu
jpeg_v2_5_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)56614f43e8fSLeo Liu static int jpeg_v2_5_set_interrupt_state(struct amdgpu_device *adev,
56714f43e8fSLeo Liu struct amdgpu_irq_src *source,
56814f43e8fSLeo Liu unsigned type,
56914f43e8fSLeo Liu enum amdgpu_interrupt_state state)
57014f43e8fSLeo Liu {
57114f43e8fSLeo Liu return 0;
57214f43e8fSLeo Liu }
57314f43e8fSLeo Liu
jpeg_v2_6_set_ras_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned int type,enum amdgpu_interrupt_state state)574674f90f8SHoratio Zhang static int jpeg_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,
575674f90f8SHoratio Zhang struct amdgpu_irq_src *source,
576674f90f8SHoratio Zhang unsigned int type,
577674f90f8SHoratio Zhang enum amdgpu_interrupt_state state)
578674f90f8SHoratio Zhang {
579674f90f8SHoratio Zhang return 0;
580674f90f8SHoratio Zhang }
581674f90f8SHoratio Zhang
jpeg_v2_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)58214f43e8fSLeo Liu static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev,
58314f43e8fSLeo Liu struct amdgpu_irq_src *source,
58414f43e8fSLeo Liu struct amdgpu_iv_entry *entry)
58514f43e8fSLeo Liu {
58614f43e8fSLeo Liu uint32_t ip_instance;
58714f43e8fSLeo Liu
58814f43e8fSLeo Liu switch (entry->client_id) {
58914f43e8fSLeo Liu case SOC15_IH_CLIENTID_VCN:
59014f43e8fSLeo Liu ip_instance = 0;
59114f43e8fSLeo Liu break;
59214f43e8fSLeo Liu case SOC15_IH_CLIENTID_VCN1:
59314f43e8fSLeo Liu ip_instance = 1;
59414f43e8fSLeo Liu break;
59514f43e8fSLeo Liu default:
59614f43e8fSLeo Liu DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
59714f43e8fSLeo Liu return 0;
59814f43e8fSLeo Liu }
59914f43e8fSLeo Liu
60014f43e8fSLeo Liu DRM_DEBUG("IH: JPEG TRAP\n");
60114f43e8fSLeo Liu
60214f43e8fSLeo Liu switch (entry->src_id) {
60314f43e8fSLeo Liu case VCN_2_0__SRCID__JPEG_DECODE:
604bc224553SJames Zhu amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
60514f43e8fSLeo Liu break;
60614f43e8fSLeo Liu default:
60714f43e8fSLeo Liu DRM_ERROR("Unhandled interrupt: %d %d\n",
60814f43e8fSLeo Liu entry->src_id, entry->src_data[0]);
60914f43e8fSLeo Liu break;
61014f43e8fSLeo Liu }
61114f43e8fSLeo Liu
61214f43e8fSLeo Liu return 0;
61314f43e8fSLeo Liu }
61414f43e8fSLeo Liu
61514f43e8fSLeo Liu static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
61614f43e8fSLeo Liu .name = "jpeg_v2_5",
61714f43e8fSLeo Liu .early_init = jpeg_v2_5_early_init,
61814f43e8fSLeo Liu .late_init = NULL,
61914f43e8fSLeo Liu .sw_init = jpeg_v2_5_sw_init,
62014f43e8fSLeo Liu .sw_fini = jpeg_v2_5_sw_fini,
62114f43e8fSLeo Liu .hw_init = jpeg_v2_5_hw_init,
62214f43e8fSLeo Liu .hw_fini = jpeg_v2_5_hw_fini,
62314f43e8fSLeo Liu .suspend = jpeg_v2_5_suspend,
62414f43e8fSLeo Liu .resume = jpeg_v2_5_resume,
62514f43e8fSLeo Liu .is_idle = jpeg_v2_5_is_idle,
62614f43e8fSLeo Liu .wait_for_idle = jpeg_v2_5_wait_for_idle,
62714f43e8fSLeo Liu .check_soft_reset = NULL,
62814f43e8fSLeo Liu .pre_soft_reset = NULL,
62914f43e8fSLeo Liu .soft_reset = NULL,
63014f43e8fSLeo Liu .post_soft_reset = NULL,
63114f43e8fSLeo Liu .set_clockgating_state = jpeg_v2_5_set_clockgating_state,
63214f43e8fSLeo Liu .set_powergating_state = jpeg_v2_5_set_powergating_state,
633e21d253bSSunil Khatri .dump_ip_state = NULL,
63440356542SSunil Khatri .print_ip_state = NULL,
63514f43e8fSLeo Liu };
63614f43e8fSLeo Liu
637ff6885acSJames Zhu static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
638ff6885acSJames Zhu .name = "jpeg_v2_6",
639ff6885acSJames Zhu .early_init = jpeg_v2_5_early_init,
640ff6885acSJames Zhu .late_init = NULL,
641ff6885acSJames Zhu .sw_init = jpeg_v2_5_sw_init,
642ff6885acSJames Zhu .sw_fini = jpeg_v2_5_sw_fini,
643ff6885acSJames Zhu .hw_init = jpeg_v2_5_hw_init,
644ff6885acSJames Zhu .hw_fini = jpeg_v2_5_hw_fini,
645ff6885acSJames Zhu .suspend = jpeg_v2_5_suspend,
646ff6885acSJames Zhu .resume = jpeg_v2_5_resume,
647ff6885acSJames Zhu .is_idle = jpeg_v2_5_is_idle,
648ff6885acSJames Zhu .wait_for_idle = jpeg_v2_5_wait_for_idle,
649ff6885acSJames Zhu .check_soft_reset = NULL,
650ff6885acSJames Zhu .pre_soft_reset = NULL,
651ff6885acSJames Zhu .soft_reset = NULL,
652ff6885acSJames Zhu .post_soft_reset = NULL,
653ff6885acSJames Zhu .set_clockgating_state = jpeg_v2_5_set_clockgating_state,
654ff6885acSJames Zhu .set_powergating_state = jpeg_v2_5_set_powergating_state,
655e21d253bSSunil Khatri .dump_ip_state = NULL,
65640356542SSunil Khatri .print_ip_state = NULL,
657ff6885acSJames Zhu };
658ff6885acSJames Zhu
65914f43e8fSLeo Liu static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {
66014f43e8fSLeo Liu .type = AMDGPU_RING_TYPE_VCN_JPEG,
66114f43e8fSLeo Liu .align_mask = 0xf,
66214f43e8fSLeo Liu .get_rptr = jpeg_v2_5_dec_ring_get_rptr,
66314f43e8fSLeo Liu .get_wptr = jpeg_v2_5_dec_ring_get_wptr,
66414f43e8fSLeo Liu .set_wptr = jpeg_v2_5_dec_ring_set_wptr,
665*3a23aa0bSDavid (Ming Qiang) Wu .parse_cs = jpeg_v2_dec_ring_parse_cs,
66614f43e8fSLeo Liu .emit_frame_size =
66714f43e8fSLeo Liu SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
66814f43e8fSLeo Liu SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
66914f43e8fSLeo Liu 8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */
67014f43e8fSLeo Liu 18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */
67114f43e8fSLeo Liu 8 + 16,
67214f43e8fSLeo Liu .emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */
67314f43e8fSLeo Liu .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
67414f43e8fSLeo Liu .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
67514f43e8fSLeo Liu .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
67614f43e8fSLeo Liu .test_ring = amdgpu_jpeg_dec_ring_test_ring,
67714f43e8fSLeo Liu .test_ib = amdgpu_jpeg_dec_ring_test_ib,
67814f43e8fSLeo Liu .insert_nop = jpeg_v2_0_dec_ring_nop,
67914f43e8fSLeo Liu .insert_start = jpeg_v2_0_dec_ring_insert_start,
68014f43e8fSLeo Liu .insert_end = jpeg_v2_0_dec_ring_insert_end,
68114f43e8fSLeo Liu .pad_ib = amdgpu_ring_generic_pad_ib,
68214f43e8fSLeo Liu .begin_use = amdgpu_jpeg_ring_begin_use,
68314f43e8fSLeo Liu .end_use = amdgpu_jpeg_ring_end_use,
68414f43e8fSLeo Liu .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
68514f43e8fSLeo Liu .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
68614f43e8fSLeo Liu .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
68714f43e8fSLeo Liu };
68814f43e8fSLeo Liu
689ff6885acSJames Zhu static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = {
690ff6885acSJames Zhu .type = AMDGPU_RING_TYPE_VCN_JPEG,
691ff6885acSJames Zhu .align_mask = 0xf,
692ff6885acSJames Zhu .get_rptr = jpeg_v2_5_dec_ring_get_rptr,
693ff6885acSJames Zhu .get_wptr = jpeg_v2_5_dec_ring_get_wptr,
694ff6885acSJames Zhu .set_wptr = jpeg_v2_5_dec_ring_set_wptr,
695*3a23aa0bSDavid (Ming Qiang) Wu .parse_cs = jpeg_v2_dec_ring_parse_cs,
696ff6885acSJames Zhu .emit_frame_size =
697ff6885acSJames Zhu SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
698ff6885acSJames Zhu SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
699ff6885acSJames Zhu 8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */
700ff6885acSJames Zhu 18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */
701ff6885acSJames Zhu 8 + 16,
702ff6885acSJames Zhu .emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */
703ff6885acSJames Zhu .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
704ff6885acSJames Zhu .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
705ff6885acSJames Zhu .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
706ff6885acSJames Zhu .test_ring = amdgpu_jpeg_dec_ring_test_ring,
707ff6885acSJames Zhu .test_ib = amdgpu_jpeg_dec_ring_test_ib,
708ff6885acSJames Zhu .insert_nop = jpeg_v2_0_dec_ring_nop,
709c6051149SJames Zhu .insert_start = jpeg_v2_6_dec_ring_insert_start,
710c6051149SJames Zhu .insert_end = jpeg_v2_6_dec_ring_insert_end,
711ff6885acSJames Zhu .pad_ib = amdgpu_ring_generic_pad_ib,
712ff6885acSJames Zhu .begin_use = amdgpu_jpeg_ring_begin_use,
713ff6885acSJames Zhu .end_use = amdgpu_jpeg_ring_end_use,
714ff6885acSJames Zhu .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
715ff6885acSJames Zhu .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
716ff6885acSJames Zhu .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
717ff6885acSJames Zhu };
718ff6885acSJames Zhu
jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device * adev)71914f43e8fSLeo Liu static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
72014f43e8fSLeo Liu {
72114f43e8fSLeo Liu int i;
72214f43e8fSLeo Liu
72314f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
72414f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
72514f43e8fSLeo Liu continue;
726ff6885acSJames Zhu if (adev->asic_type == CHIP_ARCTURUS)
727bc224553SJames Zhu adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_5_dec_ring_vm_funcs;
728ff6885acSJames Zhu else /* CHIP_ALDEBARAN */
729bc224553SJames Zhu adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_6_dec_ring_vm_funcs;
730bc224553SJames Zhu adev->jpeg.inst[i].ring_dec->me = i;
73114f43e8fSLeo Liu }
73214f43e8fSLeo Liu }
73314f43e8fSLeo Liu
73414f43e8fSLeo Liu static const struct amdgpu_irq_src_funcs jpeg_v2_5_irq_funcs = {
73514f43e8fSLeo Liu .set = jpeg_v2_5_set_interrupt_state,
73614f43e8fSLeo Liu .process = jpeg_v2_5_process_interrupt,
73714f43e8fSLeo Liu };
73814f43e8fSLeo Liu
739674f90f8SHoratio Zhang static const struct amdgpu_irq_src_funcs jpeg_v2_6_ras_irq_funcs = {
740674f90f8SHoratio Zhang .set = jpeg_v2_6_set_ras_interrupt_state,
741674f90f8SHoratio Zhang .process = amdgpu_jpeg_process_poison_irq,
742674f90f8SHoratio Zhang };
743674f90f8SHoratio Zhang
jpeg_v2_5_set_irq_funcs(struct amdgpu_device * adev)74414f43e8fSLeo Liu static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev)
74514f43e8fSLeo Liu {
74614f43e8fSLeo Liu int i;
74714f43e8fSLeo Liu
74814f43e8fSLeo Liu for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
74914f43e8fSLeo Liu if (adev->jpeg.harvest_config & (1 << i))
75014f43e8fSLeo Liu continue;
75114f43e8fSLeo Liu
75214f43e8fSLeo Liu adev->jpeg.inst[i].irq.num_types = 1;
75314f43e8fSLeo Liu adev->jpeg.inst[i].irq.funcs = &jpeg_v2_5_irq_funcs;
754674f90f8SHoratio Zhang
755674f90f8SHoratio Zhang adev->jpeg.inst[i].ras_poison_irq.num_types = 1;
756674f90f8SHoratio Zhang adev->jpeg.inst[i].ras_poison_irq.funcs = &jpeg_v2_6_ras_irq_funcs;
75714f43e8fSLeo Liu }
75814f43e8fSLeo Liu }
75914f43e8fSLeo Liu
7600b0fb6daSchenxuebing const struct amdgpu_ip_block_version jpeg_v2_5_ip_block = {
76114f43e8fSLeo Liu .type = AMD_IP_BLOCK_TYPE_JPEG,
76214f43e8fSLeo Liu .major = 2,
76314f43e8fSLeo Liu .minor = 5,
76414f43e8fSLeo Liu .rev = 0,
76514f43e8fSLeo Liu .funcs = &jpeg_v2_5_ip_funcs,
76614f43e8fSLeo Liu };
767ff6885acSJames Zhu
7680b0fb6daSchenxuebing const struct amdgpu_ip_block_version jpeg_v2_6_ip_block = {
769ff6885acSJames Zhu .type = AMD_IP_BLOCK_TYPE_JPEG,
770ff6885acSJames Zhu .major = 2,
771ff6885acSJames Zhu .minor = 6,
772ff6885acSJames Zhu .rev = 0,
773ff6885acSJames Zhu .funcs = &jpeg_v2_6_ip_funcs,
774ff6885acSJames Zhu };
775749831acSMohammad Zafar Ziya
jpeg_v2_6_query_poison_by_instance(struct amdgpu_device * adev,uint32_t instance,uint32_t sub_block)776749831acSMohammad Zafar Ziya static uint32_t jpeg_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
777749831acSMohammad Zafar Ziya uint32_t instance, uint32_t sub_block)
778749831acSMohammad Zafar Ziya {
779749831acSMohammad Zafar Ziya uint32_t poison_stat = 0, reg_value = 0;
780749831acSMohammad Zafar Ziya
781749831acSMohammad Zafar Ziya switch (sub_block) {
782749831acSMohammad Zafar Ziya case AMDGPU_JPEG_V2_6_JPEG0:
783749831acSMohammad Zafar Ziya reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG0_STATUS);
784749831acSMohammad Zafar Ziya poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG0_STATUS, POISONED_PF);
785749831acSMohammad Zafar Ziya break;
786749831acSMohammad Zafar Ziya case AMDGPU_JPEG_V2_6_JPEG1:
787749831acSMohammad Zafar Ziya reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG1_STATUS);
788749831acSMohammad Zafar Ziya poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG1_STATUS, POISONED_PF);
789749831acSMohammad Zafar Ziya break;
790749831acSMohammad Zafar Ziya default:
791749831acSMohammad Zafar Ziya break;
792749831acSMohammad Zafar Ziya }
793749831acSMohammad Zafar Ziya
794749831acSMohammad Zafar Ziya if (poison_stat)
795749831acSMohammad Zafar Ziya dev_info(adev->dev, "Poison detected in JPEG%d sub_block%d\n",
796749831acSMohammad Zafar Ziya instance, sub_block);
797749831acSMohammad Zafar Ziya
798749831acSMohammad Zafar Ziya return poison_stat;
799749831acSMohammad Zafar Ziya }
800749831acSMohammad Zafar Ziya
jpeg_v2_6_query_ras_poison_status(struct amdgpu_device * adev)801749831acSMohammad Zafar Ziya static bool jpeg_v2_6_query_ras_poison_status(struct amdgpu_device *adev)
802749831acSMohammad Zafar Ziya {
803749831acSMohammad Zafar Ziya uint32_t inst = 0, sub = 0, poison_stat = 0;
804749831acSMohammad Zafar Ziya
805749831acSMohammad Zafar Ziya for (inst = 0; inst < adev->jpeg.num_jpeg_inst; inst++)
806749831acSMohammad Zafar Ziya for (sub = 0; sub < AMDGPU_JPEG_V2_6_MAX_SUB_BLOCK; sub++)
807749831acSMohammad Zafar Ziya poison_stat +=
808749831acSMohammad Zafar Ziya jpeg_v2_6_query_poison_by_instance(adev, inst, sub);
809749831acSMohammad Zafar Ziya
810749831acSMohammad Zafar Ziya return !!poison_stat;
811749831acSMohammad Zafar Ziya }
812749831acSMohammad Zafar Ziya
813749831acSMohammad Zafar Ziya const struct amdgpu_ras_block_hw_ops jpeg_v2_6_ras_hw_ops = {
814749831acSMohammad Zafar Ziya .query_poison_status = jpeg_v2_6_query_ras_poison_status,
815749831acSMohammad Zafar Ziya };
816749831acSMohammad Zafar Ziya
817749831acSMohammad Zafar Ziya static struct amdgpu_jpeg_ras jpeg_v2_6_ras = {
818749831acSMohammad Zafar Ziya .ras_block = {
819749831acSMohammad Zafar Ziya .hw_ops = &jpeg_v2_6_ras_hw_ops,
820674f90f8SHoratio Zhang .ras_late_init = amdgpu_jpeg_ras_late_init,
821749831acSMohammad Zafar Ziya },
822749831acSMohammad Zafar Ziya };
823749831acSMohammad Zafar Ziya
jpeg_v2_5_set_ras_funcs(struct amdgpu_device * adev)824749831acSMohammad Zafar Ziya static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev)
825749831acSMohammad Zafar Ziya {
8264e8303cfSLijo Lazar switch (amdgpu_ip_version(adev, JPEG_HWIP, 0)) {
827749831acSMohammad Zafar Ziya case IP_VERSION(2, 6, 0):
828749831acSMohammad Zafar Ziya adev->jpeg.ras = &jpeg_v2_6_ras;
829749831acSMohammad Zafar Ziya break;
830749831acSMohammad Zafar Ziya default:
831749831acSMohammad Zafar Ziya break;
832749831acSMohammad Zafar Ziya }
833749831acSMohammad Zafar Ziya }
834