From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?ISO-8859-1?Q?Christian_K=F6nig?= Subject: Re: [PATCH 023/165] drm/radeon/cik: fill in startup/shutdown callbacks (v4) Date: Wed, 26 Jun 2013 17:03:52 +0200 Message-ID: <51CB02D8.1010203@vodafone.de> References: <1372253045-17042-1-git-send-email-alexdeucher@gmail.com> <1372253045-17042-24-git-send-email-alexdeucher@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1"; Format="flowed" Content-Transfer-Encoding: quoted-printable Return-path: Received: from outgoing.email.vodafone.de (outgoing.email.vodafone.de [139.7.28.128]) by gabe.freedesktop.org (Postfix) with ESMTP id 7F1CEE6373 for ; Wed, 26 Jun 2013 08:03:57 -0700 (PDT) In-Reply-To: <1372253045-17042-24-git-send-email-alexdeucher@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: alexdeucher@gmail.com Cc: Alex Deucher , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org Am 26.06.2013 15:21, schrieb alexdeucher@gmail.com: > From: Alex Deucher > > v2: update to latest driver changes > v3: properly tear down vm on suspend > v4: fix up irq init ordering > > Signed-off-by: Alex Deucher Just a copy&paste error, but some comments are referring to cayman and = r500/r700 generations. With that fixed the patch is: Reviewed-by: Christian K=F6nig > --- > drivers/gpu/drm/radeon/cik.c | 340 +++++++++++++++++++++++++++++++++++= +++++++ > 1 files changed, 340 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c > index cf1e0b1..cbc64a2 100644 > --- a/drivers/gpu/drm/radeon/cik.c > +++ b/drivers/gpu/drm/radeon/cik.c > @@ -73,6 +73,8 @@ extern void r600_ih_ring_fini(struct radeon_device *rde= v); > extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergr= een_mc_save *save); > extern void evergreen_mc_resume(struct radeon_device *rdev, struct ever= green_mc_save *save); > extern void si_vram_gtt_location(struct radeon_device *rdev, struct rad= eon_mc *mc); > +extern void si_rlc_fini(struct radeon_device *rdev); > +extern int si_rlc_init(struct radeon_device *rdev); > = > #define BONAIRE_IO_MC_REGS_SIZE 36 > = > @@ -4681,3 +4683,341 @@ restart_ih: > = > return IRQ_HANDLED; > } > + > +/* > + * startup/shutdown callbacks > + */ > +/** > + * cik_startup - program the asic to a functional state > + * > + * @rdev: radeon_device pointer > + * > + * Programs the asic to a functional state (CIK). > + * Called by cik_init() and cik_resume(). > + * Returns 0 for success, error for failure. > + */ > +static int cik_startup(struct radeon_device *rdev) > +{ > + struct radeon_ring *ring; > + int r; > + > + if (rdev->flags & RADEON_IS_IGP) { > + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || > + !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { > + r =3D cik_init_microcode(rdev); > + if (r) { > + DRM_ERROR("Failed to load firmware!\n"); > + return r; > + } > + } > + } else { > + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || > + !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw || > + !rdev->mc_fw) { > + r =3D cik_init_microcode(rdev); > + if (r) { > + DRM_ERROR("Failed to load firmware!\n"); > + return r; > + } > + } > + > + r =3D ci_mc_load_microcode(rdev); > + if (r) { > + DRM_ERROR("Failed to load MC firmware!\n"); > + return r; > + } > + } > + > + r =3D r600_vram_scratch_init(rdev); > + if (r) > + return r; > + > + cik_mc_program(rdev); > + r =3D cik_pcie_gart_enable(rdev); > + if (r) > + return r; > + cik_gpu_init(rdev); > + > + /* allocate rlc buffers */ > + r =3D si_rlc_init(rdev); > + if (r) { > + DRM_ERROR("Failed to init rlc BOs!\n"); > + return r; > + } > + > + /* allocate wb buffer */ > + r =3D radeon_wb_init(rdev); > + if (r) > + return r; > + > + r =3D radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); > + if (r) { > + dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); > + return r; > + } > + > + r =3D radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); > + if (r) { > + dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); > + return r; > + } > + > + r =3D radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); > + if (r) { > + dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); > + return r; > + } > + > + /* Enable IRQ */ > + if (!rdev->irq.installed) { > + r =3D radeon_irq_kms_init(rdev); > + if (r) > + return r; > + } > + > + r =3D cik_irq_init(rdev); > + if (r) { > + DRM_ERROR("radeon: IH init failed (%d).\n", r); > + radeon_irq_kms_fini(rdev); > + return r; > + } > + cik_irq_set(rdev); > + > + ring =3D &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; > + r =3D radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_O= FFSET, > + CP_RB0_RPTR, CP_RB0_WPTR, > + 0, 0xfffff, RADEON_CP_PACKET2); > + if (r) > + return r; > + > + ring =3D &rdev->ring[R600_RING_TYPE_DMA_INDEX]; > + r =3D radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OF= FSET, > + SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET, > + SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET, > + 2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); > + if (r) > + return r; > + > + ring =3D &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; > + r =3D radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR= _OFFSET, > + SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET, > + SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET, > + 2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); > + if (r) > + return r; > + > + r =3D cik_cp_resume(rdev); > + if (r) > + return r; > + > + r =3D cik_sdma_resume(rdev); > + if (r) > + return r; > + > + r =3D radeon_ib_pool_init(rdev); > + if (r) { > + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); > + return r; > + } > + > + r =3D radeon_vm_manager_init(rdev); > + if (r) { > + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); > + return r; > + } > + > + return 0; > +} > + > +/** > + * cik_resume - resume the asic to a functional state > + * > + * @rdev: radeon_device pointer > + * > + * Programs the asic to a functional state (CIK). > + * Called at resume. > + * Returns 0 for success, error for failure. > + */ > +int cik_resume(struct radeon_device *rdev) > +{ > + int r; > + > + /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, > + * posting will perform necessary task to bring back GPU into good > + * shape. > + */ > + /* post card */ > + atom_asic_init(rdev->mode_info.atom_context); > + > + rdev->accel_working =3D true; > + r =3D cik_startup(rdev); > + if (r) { > + DRM_ERROR("cik startup failed on resume\n"); > + rdev->accel_working =3D false; > + return r; > + } > + > + return r; > + > +} > + > +/** > + * cik_suspend - suspend the asic > + * > + * @rdev: radeon_device pointer > + * > + * Bring the chip into a state suitable for suspend (CIK). > + * Called at suspend. > + * Returns 0 for success. > + */ > +int cik_suspend(struct radeon_device *rdev) > +{ > + radeon_vm_manager_fini(rdev); > + cik_cp_enable(rdev, false); > + cik_sdma_enable(rdev, false); > + cik_irq_suspend(rdev); > + radeon_wb_disable(rdev); > + cik_pcie_gart_disable(rdev); > + return 0; > +} > + > +/* Plan is to move initialization in that function and use > + * helper function so that radeon_device_init pretty much > + * do nothing more than calling asic specific function. This > + * should also allow to remove a bunch of callback function > + * like vram_info. > + */ > +/** > + * cik_init - asic specific driver and hw init > + * > + * @rdev: radeon_device pointer > + * > + * Setup asic specific driver variables and program the hw > + * to a functional state (CIK). > + * Called at driver startup. > + * Returns 0 for success, errors for failure. > + */ > +int cik_init(struct radeon_device *rdev) > +{ > + struct radeon_ring *ring; > + int r; > + > + /* Read BIOS */ > + if (!radeon_get_bios(rdev)) { > + if (ASIC_IS_AVIVO(rdev)) > + return -EINVAL; > + } > + /* Must be an ATOMBIOS */ > + if (!rdev->is_atom_bios) { > + dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); > + return -EINVAL; > + } > + r =3D radeon_atombios_init(rdev); > + if (r) > + return r; > + > + /* Post card if necessary */ > + if (!radeon_card_posted(rdev)) { > + if (!rdev->bios) { > + dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); > + return -EINVAL; > + } > + DRM_INFO("GPU not posted. posting now...\n"); > + atom_asic_init(rdev->mode_info.atom_context); > + } > + /* Initialize scratch registers */ > + cik_scratch_init(rdev); > + /* Initialize surface registers */ > + radeon_surface_init(rdev); > + /* Initialize clocks */ > + radeon_get_clock_info(rdev->ddev); > + > + /* Fence driver */ > + r =3D radeon_fence_driver_init(rdev); > + if (r) > + return r; > + > + /* initialize memory controller */ > + r =3D cik_mc_init(rdev); > + if (r) > + return r; > + /* Memory manager */ > + r =3D radeon_bo_init(rdev); > + if (r) > + return r; > + > + ring =3D &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; > + ring->ring_obj =3D NULL; > + r600_ring_init(rdev, ring, 1024 * 1024); > + > + ring =3D &rdev->ring[R600_RING_TYPE_DMA_INDEX]; > + ring->ring_obj =3D NULL; > + r600_ring_init(rdev, ring, 256 * 1024); > + > + ring =3D &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; > + ring->ring_obj =3D NULL; > + r600_ring_init(rdev, ring, 256 * 1024); > + > + rdev->ih.ring_obj =3D NULL; > + r600_ih_ring_init(rdev, 64 * 1024); > + > + r =3D r600_pcie_gart_init(rdev); > + if (r) > + return r; > + > + rdev->accel_working =3D true; > + r =3D cik_startup(rdev); > + if (r) { > + dev_err(rdev->dev, "disabling GPU acceleration\n"); > + cik_cp_fini(rdev); > + cik_sdma_fini(rdev); > + cik_irq_fini(rdev); > + si_rlc_fini(rdev); > + radeon_wb_fini(rdev); > + radeon_ib_pool_fini(rdev); > + radeon_vm_manager_fini(rdev); > + radeon_irq_kms_fini(rdev); > + cik_pcie_gart_fini(rdev); > + rdev->accel_working =3D false; > + } > + > + /* Don't start up if the MC ucode is missing. > + * The default clocks and voltages before the MC ucode > + * is loaded are not suffient for advanced operations. > + */ > + if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { > + DRM_ERROR("radeon: MC ucode required for NI+.\n"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +/** > + * cik_fini - asic specific driver and hw fini > + * > + * @rdev: radeon_device pointer > + * > + * Tear down the asic specific driver variables and program the hw > + * to an idle state (CIK). > + * Called at driver unload. > + */ > +void cik_fini(struct radeon_device *rdev) > +{ > + cik_cp_fini(rdev); > + cik_sdma_fini(rdev); > + cik_irq_fini(rdev); > + si_rlc_fini(rdev); > + radeon_wb_fini(rdev); > + radeon_vm_manager_fini(rdev); > + radeon_ib_pool_fini(rdev); > + radeon_irq_kms_fini(rdev); > + cik_pcie_gart_fini(rdev); > + r600_vram_scratch_fini(rdev); > + radeon_gem_fini(rdev); > + radeon_fence_driver_fini(rdev); > + radeon_bo_fini(rdev); > + radeon_atombios_fini(rdev); > + kfree(rdev->bios); > + rdev->bios =3D NULL; > +}