2014-12-22 17:26:51 -05:00
/*
* Copyright 2014 Advanced Micro Devices , Inc .
*
* 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 : Slava Grigorev < slava . grigorev @ amd . com >
*/
2014-12-06 20:19:16 -05:00
# include <linux/gcd.h>
2014-12-22 17:26:51 -05:00
# include <drm/drmP.h>
2014-12-01 13:49:39 -05:00
# include <drm/drm_crtc.h>
2014-12-22 17:26:51 -05:00
# include "radeon.h"
2014-12-01 13:49:39 -05:00
# include "atom.h"
# include "radeon_audio.h"
2014-12-22 17:26:51 -05:00
void r600_audio_enable ( struct radeon_device * rdev , struct r600_audio_pin * pin ,
u8 enable_mask ) ;
2014-12-03 15:29:53 -05:00
void dce4_audio_enable ( struct radeon_device * rdev , struct r600_audio_pin * pin ,
u8 enable_mask ) ;
2014-12-22 17:26:51 -05:00
void dce6_audio_enable ( struct radeon_device * rdev , struct r600_audio_pin * pin ,
u8 enable_mask ) ;
2014-12-01 13:49:39 -05:00
u32 dce6_endpoint_rreg ( struct radeon_device * rdev , u32 offset , u32 reg ) ;
void dce6_endpoint_wreg ( struct radeon_device * rdev ,
u32 offset , u32 reg , u32 v ) ;
2015-01-22 10:41:55 -05:00
void dce3_2_afmt_write_sad_regs ( struct drm_encoder * encoder ,
struct cea_sad * sads , int sad_count ) ;
void evergreen_hdmi_write_sad_regs ( struct drm_encoder * encoder ,
struct cea_sad * sads , int sad_count ) ;
void dce6_afmt_write_sad_regs ( struct drm_encoder * encoder ,
struct cea_sad * sads , int sad_count ) ;
2014-12-01 18:02:57 -05:00
void dce3_2_afmt_hdmi_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
void dce3_2_afmt_dp_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
void dce4_afmt_hdmi_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
void dce4_afmt_dp_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
void dce6_afmt_hdmi_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
void dce6_afmt_dp_write_speaker_allocation ( struct drm_encoder * encoder ,
u8 * sadb , int sad_count ) ;
2014-12-02 11:20:48 -05:00
void dce4_afmt_write_latency_fields ( struct drm_encoder * encoder ,
struct drm_connector * connector , struct drm_display_mode * mode ) ;
void dce6_afmt_write_latency_fields ( struct drm_encoder * encoder ,
struct drm_connector * connector , struct drm_display_mode * mode ) ;
2014-12-02 15:22:43 -05:00
struct r600_audio_pin * r600_audio_get_pin ( struct radeon_device * rdev ) ;
struct r600_audio_pin * dce6_audio_get_pin ( struct radeon_device * rdev ) ;
2014-12-02 17:27:29 -05:00
void dce6_afmt_select_pin ( struct drm_encoder * encoder ) ;
2014-12-05 13:38:31 -05:00
void r600_hdmi_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
void dce3_2_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
void dce4_hdmi_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
void dce4_dp_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
void dce6_hdmi_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
void dce6_dp_audio_set_dto ( struct radeon_device * rdev ,
struct radeon_crtc * crtc , unsigned int clock ) ;
2014-12-08 18:28:33 -05:00
void r600_set_avi_packet ( struct radeon_device * rdev , u32 offset ,
2014-12-05 17:59:56 -05:00
unsigned char * buffer , size_t size ) ;
2014-12-08 18:28:33 -05:00
void evergreen_set_avi_packet ( struct radeon_device * rdev , u32 offset ,
2014-12-05 17:59:56 -05:00
unsigned char * buffer , size_t size ) ;
2014-12-06 20:19:16 -05:00
void r600_hdmi_update_acr ( struct drm_encoder * encoder , long offset ,
const struct radeon_hdmi_acr * acr ) ;
void dce3_2_hdmi_update_acr ( struct drm_encoder * encoder , long offset ,
const struct radeon_hdmi_acr * acr ) ;
void evergreen_hdmi_update_acr ( struct drm_encoder * encoder , long offset ,
const struct radeon_hdmi_acr * acr ) ;
2015-01-20 19:20:52 -05:00
void r600_set_vbi_packet ( struct drm_encoder * encoder , u32 offset ) ;
void dce4_set_vbi_packet ( struct drm_encoder * encoder , u32 offset ) ;
2014-12-08 16:25:37 -05:00
void dce4_hdmi_set_color_depth ( struct drm_encoder * encoder ,
u32 offset , int bpc ) ;
2014-12-09 16:44:18 -05:00
void r600_set_audio_packet ( struct drm_encoder * encoder , u32 offset ) ;
void dce3_2_set_audio_packet ( struct drm_encoder * encoder , u32 offset ) ;
void dce4_set_audio_packet ( struct drm_encoder * encoder , u32 offset ) ;
2014-12-09 17:17:35 -05:00
void r600_set_mute ( struct drm_encoder * encoder , u32 offset , bool mute ) ;
void dce3_2_set_mute ( struct drm_encoder * encoder , u32 offset , bool mute ) ;
void dce4_set_mute ( struct drm_encoder * encoder , u32 offset , bool mute ) ;
2014-12-10 10:43:51 -05:00
static void radeon_audio_hdmi_mode_set ( struct drm_encoder * encoder ,
struct drm_display_mode * mode ) ;
2014-12-12 17:01:42 -05:00
static void radeon_audio_dp_mode_set ( struct drm_encoder * encoder ,
struct drm_display_mode * mode ) ;
2014-12-10 14:52:43 -05:00
void r600_hdmi_enable ( struct drm_encoder * encoder , bool enable ) ;
void evergreen_hdmi_enable ( struct drm_encoder * encoder , bool enable ) ;
2015-02-27 10:04:11 -05:00
void evergreen_dp_enable ( struct drm_encoder * encoder , bool enable ) ;
2014-12-22 17:26:51 -05:00
static const u32 pin_offsets [ 7 ] =
{
( 0x5e00 - 0x5e00 ) ,
( 0x5e18 - 0x5e00 ) ,
( 0x5e30 - 0x5e00 ) ,
( 0x5e48 - 0x5e00 ) ,
( 0x5e60 - 0x5e00 ) ,
( 0x5e78 - 0x5e00 ) ,
( 0x5e90 - 0x5e00 ) ,
} ;
2014-12-01 13:49:39 -05:00
static u32 radeon_audio_rreg ( struct radeon_device * rdev , u32 offset , u32 reg )
{
return RREG32 ( reg ) ;
}
static void radeon_audio_wreg ( struct radeon_device * rdev , u32 offset ,
u32 reg , u32 v )
{
WREG32 ( reg , v ) ;
}
2014-12-05 13:38:31 -05:00
static struct radeon_audio_basic_funcs r600_funcs = {
. endpoint_rreg = radeon_audio_rreg ,
. endpoint_wreg = radeon_audio_wreg ,
. enable = r600_audio_enable ,
} ;
2014-12-01 13:49:39 -05:00
static struct radeon_audio_basic_funcs dce32_funcs = {
. endpoint_rreg = radeon_audio_rreg ,
. endpoint_wreg = radeon_audio_wreg ,
2014-12-03 15:29:53 -05:00
. enable = r600_audio_enable ,
2014-12-01 13:49:39 -05:00
} ;
static struct radeon_audio_basic_funcs dce4_funcs = {
. endpoint_rreg = radeon_audio_rreg ,
. endpoint_wreg = radeon_audio_wreg ,
2014-12-03 15:29:53 -05:00
. enable = dce4_audio_enable ,
2014-12-01 13:49:39 -05:00
} ;
static struct radeon_audio_basic_funcs dce6_funcs = {
. endpoint_rreg = dce6_endpoint_rreg ,
. endpoint_wreg = dce6_endpoint_wreg ,
2014-12-03 15:29:53 -05:00
. enable = dce6_audio_enable ,
2014-12-01 13:49:39 -05:00
} ;
2014-12-05 13:38:31 -05:00
static struct radeon_audio_funcs r600_hdmi_funcs = {
. get_pin = r600_audio_get_pin ,
. set_dto = r600_hdmi_audio_set_dto ,
2014-12-06 20:19:16 -05:00
. update_acr = r600_hdmi_update_acr ,
2015-01-20 19:20:52 -05:00
. set_vbi_packet = r600_set_vbi_packet ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = r600_set_avi_packet ,
2014-12-09 16:44:18 -05:00
. set_audio_packet = r600_set_audio_packet ,
2014-12-09 17:17:35 -05:00
. set_mute = r600_set_mute ,
2014-12-10 10:43:51 -05:00
. mode_set = radeon_audio_hdmi_mode_set ,
2014-12-10 14:52:43 -05:00
. dpms = r600_hdmi_enable ,
2014-12-05 13:38:31 -05:00
} ;
2015-01-22 10:41:55 -05:00
static struct radeon_audio_funcs dce32_hdmi_funcs = {
2014-12-02 15:22:43 -05:00
. get_pin = r600_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = dce3_2_afmt_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation ,
2014-12-05 13:38:31 -05:00
. set_dto = dce3_2_audio_set_dto ,
2014-12-06 20:19:16 -05:00
. update_acr = dce3_2_hdmi_update_acr ,
2015-01-20 19:20:52 -05:00
. set_vbi_packet = r600_set_vbi_packet ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = r600_set_avi_packet ,
2014-12-09 16:44:18 -05:00
. set_audio_packet = dce3_2_set_audio_packet ,
2014-12-09 17:17:35 -05:00
. set_mute = dce3_2_set_mute ,
2014-12-10 10:43:51 -05:00
. mode_set = radeon_audio_hdmi_mode_set ,
2014-12-10 14:52:43 -05:00
. dpms = r600_hdmi_enable ,
2015-01-22 10:41:55 -05:00
} ;
static struct radeon_audio_funcs dce32_dp_funcs = {
2014-12-02 15:22:43 -05:00
. get_pin = r600_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = dce3_2_afmt_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation ,
2014-12-05 13:38:31 -05:00
. set_dto = dce3_2_audio_set_dto ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = r600_set_avi_packet ,
2014-12-12 17:01:42 -05:00
. set_audio_packet = dce3_2_set_audio_packet ,
2015-01-22 10:41:55 -05:00
} ;
static struct radeon_audio_funcs dce4_hdmi_funcs = {
2014-12-02 15:22:43 -05:00
. get_pin = r600_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = evergreen_hdmi_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation ,
2014-12-02 11:20:48 -05:00
. write_latency_fields = dce4_afmt_write_latency_fields ,
2014-12-05 13:38:31 -05:00
. set_dto = dce4_hdmi_audio_set_dto ,
2014-12-06 20:19:16 -05:00
. update_acr = evergreen_hdmi_update_acr ,
2015-01-20 19:20:52 -05:00
. set_vbi_packet = dce4_set_vbi_packet ,
2014-12-08 16:25:37 -05:00
. set_color_depth = dce4_hdmi_set_color_depth ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = evergreen_set_avi_packet ,
2014-12-09 16:44:18 -05:00
. set_audio_packet = dce4_set_audio_packet ,
2014-12-09 17:17:35 -05:00
. set_mute = dce4_set_mute ,
2014-12-10 10:43:51 -05:00
. mode_set = radeon_audio_hdmi_mode_set ,
2014-12-10 14:52:43 -05:00
. dpms = evergreen_hdmi_enable ,
2015-01-22 10:41:55 -05:00
} ;
static struct radeon_audio_funcs dce4_dp_funcs = {
2014-12-02 15:22:43 -05:00
. get_pin = r600_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = evergreen_hdmi_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation ,
2014-12-02 11:20:48 -05:00
. write_latency_fields = dce4_afmt_write_latency_fields ,
2014-12-05 13:38:31 -05:00
. set_dto = dce4_dp_audio_set_dto ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = evergreen_set_avi_packet ,
2014-12-12 17:01:42 -05:00
. set_audio_packet = dce4_set_audio_packet ,
. mode_set = radeon_audio_dp_mode_set ,
2015-02-27 10:04:11 -05:00
. dpms = evergreen_dp_enable ,
2015-01-22 10:41:55 -05:00
} ;
static struct radeon_audio_funcs dce6_hdmi_funcs = {
2014-12-02 17:27:29 -05:00
. select_pin = dce6_afmt_select_pin ,
2014-12-02 15:22:43 -05:00
. get_pin = dce6_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = dce6_afmt_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation ,
2014-12-02 11:20:48 -05:00
. write_latency_fields = dce6_afmt_write_latency_fields ,
2014-12-05 13:38:31 -05:00
. set_dto = dce6_hdmi_audio_set_dto ,
2014-12-06 20:19:16 -05:00
. update_acr = evergreen_hdmi_update_acr ,
2015-01-20 19:20:52 -05:00
. set_vbi_packet = dce4_set_vbi_packet ,
2014-12-08 16:25:37 -05:00
. set_color_depth = dce4_hdmi_set_color_depth ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = evergreen_set_avi_packet ,
2014-12-09 16:44:18 -05:00
. set_audio_packet = dce4_set_audio_packet ,
2014-12-09 17:17:35 -05:00
. set_mute = dce4_set_mute ,
2014-12-10 10:43:51 -05:00
. mode_set = radeon_audio_hdmi_mode_set ,
2014-12-10 14:52:43 -05:00
. dpms = evergreen_hdmi_enable ,
2015-01-22 10:41:55 -05:00
} ;
static struct radeon_audio_funcs dce6_dp_funcs = {
2014-12-02 17:27:29 -05:00
. select_pin = dce6_afmt_select_pin ,
2014-12-02 15:22:43 -05:00
. get_pin = dce6_audio_get_pin ,
2015-01-22 10:41:55 -05:00
. write_sad_regs = dce6_afmt_write_sad_regs ,
2014-12-01 18:02:57 -05:00
. write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation ,
2014-12-02 11:20:48 -05:00
. write_latency_fields = dce6_afmt_write_latency_fields ,
2014-12-05 13:38:31 -05:00
. set_dto = dce6_dp_audio_set_dto ,
2014-12-08 18:28:33 -05:00
. set_avi_packet = evergreen_set_avi_packet ,
2014-12-12 17:01:42 -05:00
. set_audio_packet = dce4_set_audio_packet ,
. mode_set = radeon_audio_dp_mode_set ,
2015-03-31 11:38:48 -04:00
. dpms = evergreen_dp_enable ,
2015-01-22 10:41:55 -05:00
} ;
2015-05-18 11:11:48 -04:00
static void radeon_audio_enable ( struct radeon_device * rdev ,
struct r600_audio_pin * pin , u8 enable_mask )
{
if ( rdev - > audio . funcs - > enable )
rdev - > audio . funcs - > enable ( rdev , pin , enable_mask ) ;
}
2014-12-01 13:49:39 -05:00
static void radeon_audio_interface_init ( struct radeon_device * rdev )
{
if ( ASIC_IS_DCE6 ( rdev ) ) {
rdev - > audio . funcs = & dce6_funcs ;
2015-01-22 10:41:55 -05:00
rdev - > audio . hdmi_funcs = & dce6_hdmi_funcs ;
rdev - > audio . dp_funcs = & dce6_dp_funcs ;
2014-12-01 13:49:39 -05:00
} else if ( ASIC_IS_DCE4 ( rdev ) ) {
rdev - > audio . funcs = & dce4_funcs ;
2015-01-22 10:41:55 -05:00
rdev - > audio . hdmi_funcs = & dce4_hdmi_funcs ;
rdev - > audio . dp_funcs = & dce4_dp_funcs ;
2014-12-05 13:38:31 -05:00
} else if ( ASIC_IS_DCE32 ( rdev ) ) {
2014-12-01 13:49:39 -05:00
rdev - > audio . funcs = & dce32_funcs ;
2015-01-22 10:41:55 -05:00
rdev - > audio . hdmi_funcs = & dce32_hdmi_funcs ;
rdev - > audio . dp_funcs = & dce32_dp_funcs ;
2014-12-05 13:38:31 -05:00
} else {
rdev - > audio . funcs = & r600_funcs ;
rdev - > audio . hdmi_funcs = & r600_hdmi_funcs ;
rdev - > audio . dp_funcs = 0 ;
2014-12-01 13:49:39 -05:00
}
}
2014-12-22 17:26:51 -05:00
static int radeon_audio_chipset_supported ( struct radeon_device * rdev )
{
return ASIC_IS_DCE2 ( rdev ) & & ! ASIC_IS_NODCE ( rdev ) ;
}
int radeon_audio_init ( struct radeon_device * rdev )
{
int i ;
if ( ! radeon_audio | | ! radeon_audio_chipset_supported ( rdev ) )
return 0 ;
rdev - > audio . enabled = true ;
if ( ASIC_IS_DCE83 ( rdev ) ) /* KB: 2 streams, 3 endpoints */
rdev - > audio . num_pins = 3 ;
else if ( ASIC_IS_DCE81 ( rdev ) ) /* KV: 4 streams, 7 endpoints */
rdev - > audio . num_pins = 7 ;
else if ( ASIC_IS_DCE8 ( rdev ) ) /* BN/HW: 6 streams, 7 endpoints */
rdev - > audio . num_pins = 7 ;
else if ( ASIC_IS_DCE64 ( rdev ) ) /* OL: 2 streams, 2 endpoints */
rdev - > audio . num_pins = 2 ;
else if ( ASIC_IS_DCE61 ( rdev ) ) /* TN: 4 streams, 6 endpoints */
rdev - > audio . num_pins = 6 ;
else if ( ASIC_IS_DCE6 ( rdev ) ) /* SI: 6 streams, 6 endpoints */
rdev - > audio . num_pins = 6 ;
else
rdev - > audio . num_pins = 1 ;
for ( i = 0 ; i < rdev - > audio . num_pins ; i + + ) {
rdev - > audio . pin [ i ] . channels = - 1 ;
rdev - > audio . pin [ i ] . rate = - 1 ;
rdev - > audio . pin [ i ] . bits_per_sample = - 1 ;
rdev - > audio . pin [ i ] . status_bits = 0 ;
rdev - > audio . pin [ i ] . category_code = 0 ;
rdev - > audio . pin [ i ] . connected = false ;
rdev - > audio . pin [ i ] . offset = pin_offsets [ i ] ;
rdev - > audio . pin [ i ] . id = i ;
2014-12-01 13:49:39 -05:00
}
radeon_audio_interface_init ( rdev ) ;
/* disable audio. it will be set up later */
for ( i = 0 ; i < rdev - > audio . num_pins ; i + + )
2015-05-18 11:11:48 -04:00
radeon_audio_enable ( rdev , & rdev - > audio . pin [ i ] , 0 ) ;
2014-12-01 13:49:39 -05:00
return 0 ;
}
u32 radeon_audio_endpoint_rreg ( struct radeon_device * rdev , u32 offset , u32 reg )
{
if ( rdev - > audio . funcs - > endpoint_rreg )
return rdev - > audio . funcs - > endpoint_rreg ( rdev , offset , reg ) ;
2014-12-22 17:26:51 -05:00
return 0 ;
}
2014-12-01 13:49:39 -05:00
void radeon_audio_endpoint_wreg ( struct radeon_device * rdev , u32 offset ,
u32 reg , u32 v )
{
if ( rdev - > audio . funcs - > endpoint_wreg )
rdev - > audio . funcs - > endpoint_wreg ( rdev , offset , reg , v ) ;
}
2015-01-22 10:41:55 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_write_sad_regs ( struct drm_encoder * encoder )
2015-01-22 10:41:55 -05:00
{
struct radeon_encoder * radeon_encoder ;
struct drm_connector * connector ;
struct radeon_connector * radeon_connector = NULL ;
struct cea_sad * sads ;
int sad_count ;
list_for_each_entry ( connector ,
& encoder - > dev - > mode_config . connector_list , head ) {
if ( connector - > encoder = = encoder ) {
radeon_connector = to_radeon_connector ( connector ) ;
break ;
}
}
if ( ! radeon_connector ) {
DRM_ERROR ( " Couldn't find encoder's connector \n " ) ;
return ;
}
sad_count = drm_edid_to_sad ( radeon_connector_edid ( connector ) , & sads ) ;
if ( sad_count < = 0 ) {
DRM_ERROR ( " Couldn't read SADs: %d \n " , sad_count ) ;
return ;
}
BUG_ON ( ! sads ) ;
radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > write_sad_regs )
radeon_encoder - > audio - > write_sad_regs ( encoder , sads , sad_count ) ;
kfree ( sads ) ;
}
2014-12-01 18:02:57 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_write_speaker_allocation ( struct drm_encoder * encoder )
2014-12-01 18:02:57 -05:00
{
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
2015-01-13 12:41:40 -05:00
struct drm_connector * connector ;
struct radeon_connector * radeon_connector = NULL ;
u8 * sadb = NULL ;
int sad_count ;
2014-12-01 18:02:57 -05:00
2015-01-13 12:41:40 -05:00
list_for_each_entry ( connector ,
& encoder - > dev - > mode_config . connector_list , head ) {
if ( connector - > encoder = = encoder ) {
radeon_connector = to_radeon_connector ( connector ) ;
break ;
}
}
if ( ! radeon_connector ) {
DRM_ERROR ( " Couldn't find encoder's connector \n " ) ;
return ;
}
sad_count = drm_edid_to_speaker_allocation (
2014-12-01 18:02:57 -05:00
radeon_connector_edid ( connector ) , & sadb ) ;
2015-01-13 12:41:40 -05:00
if ( sad_count < 0 ) {
DRM_DEBUG ( " Couldn't read Speaker Allocation Data Block: %d \n " ,
sad_count ) ;
sad_count = 0 ;
}
2014-12-01 18:02:57 -05:00
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > write_speaker_allocation )
radeon_encoder - > audio - > write_speaker_allocation ( encoder , sadb , sad_count ) ;
2015-01-13 12:41:40 -05:00
kfree ( sadb ) ;
2014-12-01 18:02:57 -05:00
}
2014-12-02 11:20:48 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_write_latency_fields ( struct drm_encoder * encoder ,
2014-12-02 11:20:48 -05:00
struct drm_display_mode * mode )
{
struct radeon_encoder * radeon_encoder ;
struct drm_connector * connector ;
struct radeon_connector * radeon_connector = 0 ;
list_for_each_entry ( connector ,
& encoder - > dev - > mode_config . connector_list , head ) {
if ( connector - > encoder = = encoder ) {
radeon_connector = to_radeon_connector ( connector ) ;
break ;
}
}
if ( ! radeon_connector ) {
DRM_ERROR ( " Couldn't find encoder's connector \n " ) ;
return ;
}
radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > write_latency_fields )
radeon_encoder - > audio - > write_latency_fields ( encoder , connector , mode ) ;
}
2014-12-02 15:22:43 -05:00
struct r600_audio_pin * radeon_audio_get_pin ( struct drm_encoder * encoder )
{
struct radeon_device * rdev = encoder - > dev - > dev_private ;
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > get_pin )
return radeon_encoder - > audio - > get_pin ( rdev ) ;
return NULL ;
}
2014-12-02 17:27:29 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_select_pin ( struct drm_encoder * encoder )
2014-12-02 17:27:29 -05:00
{
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > select_pin )
radeon_encoder - > audio - > select_pin ( encoder ) ;
}
2014-12-03 15:29:53 -05:00
2014-12-11 13:11:29 -05:00
void radeon_audio_detect ( struct drm_connector * connector ,
2015-02-27 10:36:39 -05:00
enum drm_connector_status status )
2014-12-11 13:11:29 -05:00
{
struct radeon_device * rdev ;
struct radeon_encoder * radeon_encoder ;
struct radeon_encoder_atom_dig * dig ;
if ( ! connector | | ! connector - > encoder )
return ;
rdev = connector - > encoder - > dev - > dev_private ;
2015-05-04 14:35:01 -04:00
if ( ! radeon_audio_chipset_supported ( rdev ) )
return ;
2014-12-11 13:11:29 -05:00
radeon_encoder = to_radeon_encoder ( connector - > encoder ) ;
dig = radeon_encoder - > enc_priv ;
2015-04-07 09:52:42 -04:00
if ( status = = connector_status_connected ) {
2015-05-27 11:43:53 -04:00
if ( ! drm_detect_monitor_audio ( radeon_connector_edid ( connector ) ) ) {
radeon_encoder - > audio = NULL ;
return ;
}
2015-06-30 09:30:01 -04:00
if ( connector - > connector_type = = DRM_MODE_CONNECTOR_DisplayPort ) {
struct radeon_connector * radeon_connector = to_radeon_connector ( connector ) ;
2014-12-11 13:11:29 -05:00
2015-06-30 09:30:01 -04:00
if ( radeon_dp_getsinktype ( radeon_connector ) = =
CONNECTOR_OBJECT_ID_DISPLAYPORT )
radeon_encoder - > audio = rdev - > audio . dp_funcs ;
else
radeon_encoder - > audio = rdev - > audio . hdmi_funcs ;
} else {
2014-12-11 13:11:29 -05:00
radeon_encoder - > audio = rdev - > audio . hdmi_funcs ;
2015-06-30 09:30:01 -04:00
}
2014-12-11 13:11:29 -05:00
2015-02-27 10:36:39 -05:00
dig - > afmt - > pin = radeon_audio_get_pin ( connector - > encoder ) ;
2015-05-27 11:43:53 -04:00
radeon_audio_enable ( rdev , dig - > afmt - > pin , 0xf ) ;
2014-12-11 13:11:29 -05:00
} else {
radeon_audio_enable ( rdev , dig - > afmt - > pin , 0 ) ;
2015-02-27 10:36:39 -05:00
dig - > afmt - > pin = NULL ;
2014-12-11 13:11:29 -05:00
}
}
2014-12-03 17:07:01 -05:00
void radeon_audio_fini ( struct radeon_device * rdev )
{
int i ;
if ( ! rdev - > audio . enabled )
return ;
for ( i = 0 ; i < rdev - > audio . num_pins ; i + + )
2015-05-18 11:11:48 -04:00
radeon_audio_enable ( rdev , & rdev - > audio . pin [ i ] , 0 ) ;
2014-12-03 17:07:01 -05:00
rdev - > audio . enabled = false ;
}
2014-12-05 13:38:31 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_set_dto ( struct drm_encoder * encoder , unsigned int clock )
2014-12-05 13:38:31 -05:00
{
struct radeon_device * rdev = encoder - > dev - > dev_private ;
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_crtc * crtc = to_radeon_crtc ( encoder - > crtc ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > set_dto )
radeon_encoder - > audio - > set_dto ( rdev , crtc , clock ) ;
}
2014-12-05 17:59:56 -05:00
2014-12-10 10:43:51 -05:00
static int radeon_audio_set_avi_packet ( struct drm_encoder * encoder ,
2014-12-08 18:28:33 -05:00
struct drm_display_mode * mode )
2014-12-05 17:59:56 -05:00
{
2015-01-13 12:41:40 -05:00
struct radeon_device * rdev = encoder - > dev - > dev_private ;
2014-12-05 17:59:56 -05:00
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2015-02-23 17:14:47 -05:00
struct drm_connector * connector ;
struct radeon_connector * radeon_connector = NULL ;
2014-12-08 18:28:33 -05:00
u8 buffer [ HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE ] ;
struct hdmi_avi_infoframe frame ;
int err ;
2015-02-23 17:14:47 -05:00
list_for_each_entry ( connector ,
& encoder - > dev - > mode_config . connector_list , head ) {
if ( connector - > encoder = = encoder ) {
radeon_connector = to_radeon_connector ( connector ) ;
break ;
}
}
if ( ! radeon_connector ) {
DRM_ERROR ( " Couldn't find encoder's connector \n " ) ;
return - ENOENT ;
}
2014-12-08 18:28:33 -05:00
err = drm_hdmi_avi_infoframe_from_display_mode ( & frame , mode ) ;
if ( err < 0 ) {
DRM_ERROR ( " failed to setup AVI infoframe: %d \n " , err ) ;
return err ;
}
2015-02-23 17:14:47 -05:00
if ( drm_rgb_quant_range_selectable ( radeon_connector_edid ( connector ) ) ) {
if ( radeon_encoder - > output_csc = = RADEON_OUTPUT_CSC_TVRGB )
frame . quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED ;
else
frame . quantization_range = HDMI_QUANTIZATION_RANGE_FULL ;
} else {
frame . quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT ;
}
2014-12-08 18:28:33 -05:00
err = hdmi_avi_infoframe_pack ( & frame , buffer , sizeof ( buffer ) ) ;
if ( err < 0 ) {
DRM_ERROR ( " failed to pack AVI infoframe: %d \n " , err ) ;
return err ;
}
if ( dig & & dig - > afmt & &
radeon_encoder - > audio & & radeon_encoder - > audio - > set_avi_packet )
radeon_encoder - > audio - > set_avi_packet ( rdev , dig - > afmt - > offset ,
buffer , sizeof ( buffer ) ) ;
2014-12-05 17:59:56 -05:00
2014-12-08 18:28:33 -05:00
return 0 ;
2014-12-05 17:59:56 -05:00
}
2014-12-06 20:19:16 -05:00
/*
* calculate CTS and N values if they are not found in the table
*/
static void radeon_audio_calc_cts ( unsigned int clock , int * CTS , int * N , int freq )
{
int n , cts ;
unsigned long div , mul ;
/* Safe, but overly large values */
n = 128 * freq ;
cts = clock * 1000 ;
/* Smallest valid fraction */
div = gcd ( n , cts ) ;
n / = div ;
cts / = div ;
/*
* The optimal N is 128 * freq / 1000. Calculate the closest larger
* value that doesn ' t truncate any bits .
*/
mul = ( ( 128 * freq / 1000 ) + ( n - 1 ) ) / n ;
n * = mul ;
cts * = mul ;
/* Check that we are in spec (not always possible) */
if ( n < ( 128 * freq / 1500 ) )
printk ( KERN_WARNING " Calculated ACR N value is too small. You may experience audio problems. \n " ) ;
if ( n > ( 128 * freq / 300 ) )
printk ( KERN_WARNING " Calculated ACR N value is too large. You may experience audio problems. \n " ) ;
* N = n ;
* CTS = cts ;
DRM_DEBUG ( " Calculated ACR timing N=%d CTS=%d for frequency %d \n " ,
* N , * CTS , freq ) ;
}
static const struct radeon_hdmi_acr * radeon_audio_acr ( unsigned int clock )
{
static struct radeon_hdmi_acr res ;
u8 i ;
static const struct radeon_hdmi_acr hdmi_predefined_acr [ ] = {
/* 32kHz 44.1kHz 48kHz */
/* Clock N CTS N CTS N CTS */
{ 25175 , 4096 , 25175 , 28224 , 125875 , 6144 , 25175 } , /* 25,20/1.001 MHz */
{ 25200 , 4096 , 25200 , 6272 , 28000 , 6144 , 25200 } , /* 25.20 MHz */
{ 27000 , 4096 , 27000 , 6272 , 30000 , 6144 , 27000 } , /* 27.00 MHz */
{ 27027 , 4096 , 27027 , 6272 , 30030 , 6144 , 27027 } , /* 27.00*1.001 MHz */
{ 54000 , 4096 , 54000 , 6272 , 60000 , 6144 , 54000 } , /* 54.00 MHz */
{ 54054 , 4096 , 54054 , 6272 , 60060 , 6144 , 54054 } , /* 54.00*1.001 MHz */
{ 74176 , 4096 , 74176 , 5733 , 75335 , 6144 , 74176 } , /* 74.25/1.001 MHz */
{ 74250 , 4096 , 74250 , 6272 , 82500 , 6144 , 74250 } , /* 74.25 MHz */
{ 148352 , 4096 , 148352 , 5733 , 150670 , 6144 , 148352 } , /* 148.50/1.001 MHz */
{ 148500 , 4096 , 148500 , 6272 , 165000 , 6144 , 148500 } , /* 148.50 MHz */
} ;
/* Precalculated values for common clocks */
for ( i = 0 ; i < ARRAY_SIZE ( hdmi_predefined_acr ) ; i + + )
if ( hdmi_predefined_acr [ i ] . clock = = clock )
return & hdmi_predefined_acr [ i ] ;
/* And odd clocks get manually calculated */
radeon_audio_calc_cts ( clock , & res . cts_32khz , & res . n_32khz , 32000 ) ;
radeon_audio_calc_cts ( clock , & res . cts_44_1khz , & res . n_44_1khz , 44100 ) ;
radeon_audio_calc_cts ( clock , & res . cts_48khz , & res . n_48khz , 48000 ) ;
return & res ;
}
/*
* update the N and CTS parameters for a given pixel clock rate
*/
2014-12-10 10:43:51 -05:00
static void radeon_audio_update_acr ( struct drm_encoder * encoder , unsigned int clock )
2014-12-06 20:19:16 -05:00
{
2015-01-13 12:41:40 -05:00
const struct radeon_hdmi_acr * acr = radeon_audio_acr ( clock ) ;
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2014-12-06 20:19:16 -05:00
if ( ! dig | | ! dig - > afmt )
return ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > update_acr )
radeon_encoder - > audio - > update_acr ( encoder , dig - > afmt - > offset , acr ) ;
}
2015-01-20 19:20:52 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_set_vbi_packet ( struct drm_encoder * encoder )
2015-01-20 19:20:52 -05:00
{
2015-01-13 12:41:40 -05:00
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2015-01-20 19:20:52 -05:00
if ( ! dig | | ! dig - > afmt )
return ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > set_vbi_packet )
radeon_encoder - > audio - > set_vbi_packet ( encoder , dig - > afmt - > offset ) ;
}
2014-12-08 16:25:37 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_hdmi_set_color_depth ( struct drm_encoder * encoder )
2014-12-08 16:25:37 -05:00
{
int bpc = 8 ;
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
if ( ! dig | | ! dig - > afmt )
return ;
if ( encoder - > crtc ) {
struct radeon_crtc * radeon_crtc = to_radeon_crtc ( encoder - > crtc ) ;
bpc = radeon_crtc - > bpc ;
}
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > set_color_depth )
radeon_encoder - > audio - > set_color_depth ( encoder , dig - > afmt - > offset , bpc ) ;
}
2014-12-09 16:44:18 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_set_audio_packet ( struct drm_encoder * encoder )
2014-12-09 16:44:18 -05:00
{
2015-01-13 12:41:40 -05:00
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2014-12-09 16:44:18 -05:00
if ( ! dig | | ! dig - > afmt )
return ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > set_audio_packet )
radeon_encoder - > audio - > set_audio_packet ( encoder , dig - > afmt - > offset ) ;
}
2014-12-09 17:17:35 -05:00
2014-12-10 10:43:51 -05:00
static void radeon_audio_set_mute ( struct drm_encoder * encoder , bool mute )
2014-12-09 17:17:35 -05:00
{
2015-01-13 12:41:40 -05:00
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2014-12-09 17:17:35 -05:00
if ( ! dig | | ! dig - > afmt )
return ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > set_mute )
radeon_encoder - > audio - > set_mute ( encoder , dig - > afmt - > offset , mute ) ;
}
2014-12-10 10:43:51 -05:00
/*
* update the info frames with the data from the current display mode
*/
static void radeon_audio_hdmi_mode_set ( struct drm_encoder * encoder ,
2015-02-27 10:42:21 -05:00
struct drm_display_mode * mode )
2014-12-10 10:43:51 -05:00
{
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
if ( ! dig | | ! dig - > afmt )
return ;
2015-02-27 10:38:40 -05:00
radeon_audio_set_mute ( encoder , true ) ;
2014-12-10 10:43:51 -05:00
2015-02-27 10:51:40 -05:00
radeon_audio_write_speaker_allocation ( encoder ) ;
radeon_audio_write_sad_regs ( encoder ) ;
radeon_audio_write_latency_fields ( encoder , mode ) ;
2014-12-10 10:43:51 -05:00
radeon_audio_set_dto ( encoder , mode - > clock ) ;
radeon_audio_set_vbi_packet ( encoder ) ;
radeon_hdmi_set_color_depth ( encoder ) ;
radeon_audio_update_acr ( encoder , mode - > clock ) ;
radeon_audio_set_audio_packet ( encoder ) ;
radeon_audio_select_pin ( encoder ) ;
if ( radeon_audio_set_avi_packet ( encoder , mode ) < 0 )
return ;
2015-02-27 10:38:40 -05:00
radeon_audio_set_mute ( encoder , false ) ;
2014-12-10 10:43:51 -05:00
}
2014-12-12 17:01:42 -05:00
static void radeon_audio_dp_mode_set ( struct drm_encoder * encoder ,
struct drm_display_mode * mode )
{
struct drm_device * dev = encoder - > dev ;
struct radeon_device * rdev = dev - > dev_private ;
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
struct radeon_encoder_atom_dig * dig = radeon_encoder - > enc_priv ;
2015-02-27 14:43:47 -05:00
struct drm_connector * connector = radeon_get_connector_for_encoder ( encoder ) ;
struct radeon_connector * radeon_connector = to_radeon_connector ( connector ) ;
struct radeon_connector_atom_dig * dig_connector =
radeon_connector - > con_priv ;
2014-12-12 17:01:42 -05:00
if ( ! dig | | ! dig - > afmt )
return ;
2015-02-27 10:51:40 -05:00
radeon_audio_write_speaker_allocation ( encoder ) ;
radeon_audio_write_sad_regs ( encoder ) ;
radeon_audio_write_latency_fields ( encoder , mode ) ;
2015-02-27 14:43:47 -05:00
if ( rdev - > clock . dp_extclk | | ASIC_IS_DCE5 ( rdev ) )
radeon_audio_set_dto ( encoder , rdev - > clock . default_dispclk * 10 ) ;
else
radeon_audio_set_dto ( encoder , dig_connector - > dp_clock ) ;
2014-12-12 17:01:42 -05:00
radeon_audio_set_audio_packet ( encoder ) ;
radeon_audio_select_pin ( encoder ) ;
if ( radeon_audio_set_avi_packet ( encoder , mode ) < 0 )
return ;
}
2014-12-10 10:43:51 -05:00
void radeon_audio_mode_set ( struct drm_encoder * encoder ,
struct drm_display_mode * mode )
{
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > mode_set )
radeon_encoder - > audio - > mode_set ( encoder , mode ) ;
}
2014-12-10 14:52:43 -05:00
void radeon_audio_dpms ( struct drm_encoder * encoder , int mode )
{
struct radeon_encoder * radeon_encoder = to_radeon_encoder ( encoder ) ;
if ( radeon_encoder - > audio & & radeon_encoder - > audio - > dpms )
radeon_encoder - > audio - > dpms ( encoder , mode = = DRM_MODE_DPMS_ON ) ;
}