[PATCH] drm/radeon: add very basic support for audio block on DCE6

Alex Deucher alexdeucher at gmail.com
Fri Aug 2 06:01:35 PDT 2013


On Fri, Aug 2, 2013 at 4:11 AM, Rafał Miłecki <zajec5 at gmail.com> wrote:
> It doesn't allow playing anything yet, but was the most tricky part to
> RE (it's indirect access, so couldn't trace it by dumping registers).
> Now we just need to implement support for HDMI blocks.

We actually have code implemented internally for DCE6/8 that we are
hoping to release for 3.12.

Alex

>
> Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
> ---
>  drivers/gpu/drm/radeon/Makefile      |    2 +-
>  drivers/gpu/drm/radeon/dce6_afmt.c   |   88 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/radeon/radeon_asic.h |    2 +
>  drivers/gpu/drm/radeon/si.c          |    7 +++
>  drivers/gpu/drm/radeon/sid.h         |    5 ++
>  5 files changed, 103 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/radeon/dce6_afmt.c
>
> diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
> index c3df52c..6510fc4 100644
> --- a/drivers/gpu/drm/radeon/Makefile
> +++ b/drivers/gpu/drm/radeon/Makefile
> @@ -79,7 +79,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
>         si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
>         r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
>         rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
> -       trinity_smc.o ni_dpm.o si_smc.o si_dpm.o
> +       trinity_smc.o ni_dpm.o si_smc.o si_dpm.o dce6_afmt.o
>
>  radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
>  radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
> diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
> new file mode 100644
> index 0000000..0d98143
> --- /dev/null
> +++ b/drivers/gpu/drm/radeon/dce6_afmt.c
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright © 2013 Rafał Miłecki <zajec5 at gmail.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + *
> + * Authors: Rafał Miłecki
> + */
> +#include <drm/drmP.h>
> +#include <drm/radeon_drm.h>
> +#include "radeon.h"
> +#include "radeon_asic.h"
> +#include "sid.h"
> +
> +static u32 dce6_audio_read(struct radeon_device *rdev, u32 reg)
> +{
> +       WREG32(SI_AUDIO_ADDR, reg);
> +       return RREG32(SI_AUDIO_DATA);
> +}
> +
> +static void dce6_audio_write(struct radeon_device *rdev, u32 reg, u32 v)
> +{
> +       reg |= SI_AUDIO_ADDR_WRITE;
> +       WREG32(SI_AUDIO_ADDR, reg);
> +       WREG32(SI_AUDIO_DATA, v);
> +}
> +
> +static void dce6_audio_maskset(struct radeon_device *rdev, u32 reg, u32 mask,
> +                              u32 set)
> +{
> +       u32 tmp = dce6_audio_read(rdev, reg);
> +       tmp &= mask;
> +       tmp |= set & ~mask;
> +       dce6_audio_write(rdev, reg, tmp);
> +}
> +
> +static void dce6_audio_enable(struct radeon_device *rdev, bool enable)
> +{
> +       DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling");
> +
> +       if (enable) {
> +               dce6_audio_maskset(rdev, 0x54, ~0x80000000, 0x80000000);
> +       } else {
> +               dce6_audio_maskset(rdev, 0x54, ~0x80000000, 0);
> +               /* TODO: clear some bit(s) in reg 0x36 */
> +       }
> +
> +       rdev->audio_enabled = enable;
> +}
> +
> +int dce6_audio_init(struct radeon_device *rdev)
> +{
> +       if (!radeon_audio)
> +               return 0;
> +
> +       dce6_audio_enable(rdev, true);
> +
> +       rdev->audio_status.channels = -1;
> +       rdev->audio_status.rate = -1;
> +       rdev->audio_status.bits_per_sample = -1;
> +       rdev->audio_status.status_bits = 0;
> +       rdev->audio_status.category_code = 0;
> +
> +       return 0;
> +}
> +
> +void dce6_audio_fini(struct radeon_device *rdev)
> +{
> +       if (!rdev->audio_enabled)
> +               return;
> +
> +       dce6_audio_enable(rdev, false);
> +}
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index ca18957..48674ca 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -698,6 +698,8 @@ void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
>                                                     struct seq_file *m);
>  int si_dpm_force_performance_level(struct radeon_device *rdev,
>                                    enum radeon_dpm_forced_level level);
> +int dce6_audio_init(struct radeon_device *rdev);
> +void dce6_audio_fini(struct radeon_device *rdev);
>
>  /* DCE8 - CIK */
>  void dce8_bandwidth_update(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
> index d71037f..e7890bf 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -6590,6 +6590,12 @@ static int si_startup(struct radeon_device *rdev)
>                 return r;
>         }
>
> +       r = dce6_audio_init(rdev);
> +       if (r) {
> +               dev_err(rdev->dev, "Audio init failed (%d).\n", r);
> +               return r;
> +       }
> +
>         return 0;
>  }
>
> @@ -6621,6 +6627,7 @@ int si_resume(struct radeon_device *rdev)
>
>  int si_suspend(struct radeon_device *rdev)
>  {
> +       dce6_audio_fini(rdev);
>         radeon_vm_manager_fini(rdev);
>         si_cp_enable(rdev, false);
>         cayman_dma_stop(rdev);
> diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
> index 2c8da27..ddf3818 100644
> --- a/drivers/gpu/drm/radeon/sid.h
> +++ b/drivers/gpu/drm/radeon/sid.h
> @@ -618,6 +618,11 @@
>  #       define MC_WR_CLEAN_CNT(x)                         ((x) << 20)
>  #       define MC_VMID(x)                                 ((x) << 25)
>
> +#define SI_AUDIO_ADDR                                  0x5e00
> +#       define SI_AUDIO_ADDR_REG_MASK                  0xff
> +#       define SI_AUDIO_ADDR_WRITE                     (1 << 8)
> +#define SI_AUDIO_DATA                                  0x5e04
> +
>  #define        CONFIG_MEMSIZE                                  0x5428
>
>  #define INTERRUPT_CNTL                                    0x5468
> --
> 1.7.10.4
>


More information about the dri-devel mailing list