Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/hdmi: compile audio status in 1 function

This optmizes calls, registers reads and assignments.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Rafał Miłecki and committed by
Dave Airlie
3299de95 c284815d

+73 -104
+57 -78
drivers/gpu/drm/radeon/r600_audio.c
··· 63 63 || rdev->family == CHIP_RS740; 64 64 } 65 65 66 - /* 67 - * current number of channels 68 - */ 69 - int r600_audio_channels(struct radeon_device *rdev) 66 + struct r600_audio r600_audio_status(struct radeon_device *rdev) 70 67 { 71 - return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; 72 - } 68 + struct r600_audio status; 69 + uint32_t value; 73 70 74 - /* 75 - * current bits per sample 76 - */ 77 - int r600_audio_bits_per_sample(struct radeon_device *rdev) 78 - { 79 - uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4; 80 - switch (value) { 81 - case 0x0: return 8; 82 - case 0x1: return 16; 83 - case 0x2: return 20; 84 - case 0x3: return 24; 85 - case 0x4: return 32; 71 + value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); 72 + 73 + /* number of channels */ 74 + status.channels = (value & 0x7) + 1; 75 + 76 + /* bits per sample */ 77 + switch ((value & 0xF0) >> 4) { 78 + case 0x0: 79 + status.bits_per_sample = 8; 80 + break; 81 + case 0x1: 82 + status.bits_per_sample = 16; 83 + break; 84 + case 0x2: 85 + status.bits_per_sample = 20; 86 + break; 87 + case 0x3: 88 + status.bits_per_sample = 24; 89 + break; 90 + case 0x4: 91 + status.bits_per_sample = 32; 92 + break; 93 + default: 94 + dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n", 95 + (int)value); 96 + status.bits_per_sample = 16; 86 97 } 87 98 88 - dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", 89 - (int)value); 90 - 91 - return 16; 92 - } 93 - 94 - /* 95 - * current sampling rate in HZ 96 - */ 97 - int r600_audio_rate(struct radeon_device *rdev) 98 - { 99 - uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); 100 - uint32_t result; 101 - 99 + /* current sampling rate in HZ */ 102 100 if (value & 0x4000) 103 - result = 44100; 101 + status.rate = 44100; 104 102 else 105 - result = 48000; 103 + status.rate = 48000; 104 + status.rate *= ((value >> 11) & 0x7) + 1; 105 + status.rate /= ((value >> 8) & 0x7) + 1; 106 106 107 - result *= ((value >> 11) & 0x7) + 1; 108 - result /= ((value >> 8) & 0x7) + 1; 107 + value = RREG32(R600_AUDIO_STATUS_BITS); 109 108 110 - return result; 111 - } 109 + /* iec 60958 status bits */ 110 + status.status_bits = value & 0xff; 112 111 113 - /* 114 - * iec 60958 status bits 115 - */ 116 - uint8_t r600_audio_status_bits(struct radeon_device *rdev) 117 - { 118 - return RREG32(R600_AUDIO_STATUS_BITS) & 0xff; 119 - } 112 + /* iec 60958 category code */ 113 + status.category_code = (value >> 8) & 0xff; 120 114 121 - /* 122 - * iec 60958 category code 123 - */ 124 - uint8_t r600_audio_category_code(struct radeon_device *rdev) 125 - { 126 - return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff; 115 + return status; 127 116 } 128 117 129 118 /* ··· 123 134 struct radeon_device *rdev = container_of(work, struct radeon_device, 124 135 audio_work); 125 136 struct drm_device *dev = rdev->ddev; 126 - 127 - int channels = r600_audio_channels(rdev); 128 - int rate = r600_audio_rate(rdev); 129 - int bps = r600_audio_bits_per_sample(rdev); 130 - uint8_t status_bits = r600_audio_status_bits(rdev); 131 - uint8_t category_code = r600_audio_category_code(rdev); 137 + struct r600_audio audio_status = r600_audio_status(rdev); 132 138 struct drm_encoder *encoder; 133 - int changes = 0; 139 + bool changed = false; 134 140 135 - changes |= channels != rdev->audio.channels; 136 - changes |= rate != rdev->audio.rate; 137 - changes |= bps != rdev->audio.bits_per_sample; 138 - changes |= status_bits != rdev->audio.status_bits; 139 - changes |= category_code != rdev->audio.category_code; 140 - 141 - if (changes) { 142 - rdev->audio.channels = channels; 143 - rdev->audio.rate = rate; 144 - rdev->audio.bits_per_sample = bps; 145 - rdev->audio.status_bits = status_bits; 146 - rdev->audio.category_code = category_code; 141 + if (rdev->audio_status.channels != audio_status.channels || 142 + rdev->audio_status.rate != audio_status.rate || 143 + rdev->audio_status.bits_per_sample != audio_status.bits_per_sample || 144 + rdev->audio_status.status_bits != audio_status.status_bits || 145 + rdev->audio_status.category_code != audio_status.category_code) { 146 + rdev->audio_status = audio_status; 147 + changed = true; 147 148 } 148 149 149 150 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 150 151 if (!radeon_dig_encoder(encoder)) 151 152 continue; 152 - if (changes || r600_hdmi_buffer_status_changed(encoder)) 153 + if (changed || r600_hdmi_buffer_status_changed(encoder)) 153 154 r600_hdmi_update_audio_settings(encoder); 154 155 } 155 156 } ··· 161 182 WREG32_P(R600_AUDIO_ENABLE, 162 183 enable ? 0x81000000 : 0x0, ~0x81000000); 163 184 } 164 - rdev->audio.enabled = enable; 185 + rdev->audio_enabled = enable; 165 186 } 166 187 167 188 /* ··· 174 195 175 196 r600_audio_engine_enable(rdev, true); 176 197 177 - rdev->audio.channels = -1; 178 - rdev->audio.rate = -1; 179 - rdev->audio.bits_per_sample = -1; 180 - rdev->audio.status_bits = 0; 181 - rdev->audio.category_code = 0; 198 + rdev->audio_status.channels = -1; 199 + rdev->audio_status.rate = -1; 200 + rdev->audio_status.bits_per_sample = -1; 201 + rdev->audio_status.status_bits = 0; 202 + rdev->audio_status.category_code = 0; 182 203 183 204 return 0; 184 205 } ··· 247 268 */ 248 269 void r600_audio_fini(struct radeon_device *rdev) 249 270 { 250 - if (!rdev->audio.enabled) 271 + if (!rdev->audio_enabled) 251 272 return; 252 273 253 274 r600_audio_engine_enable(rdev, false);
+13 -18
drivers/gpu/drm/radeon/r600_hdmi.c
··· 398 398 struct radeon_device *rdev = dev->dev_private; 399 399 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 400 400 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 401 + struct r600_audio audio = r600_audio_status(rdev); 401 402 uint32_t offset; 402 - 403 - int channels = r600_audio_channels(rdev); 404 - int rate = r600_audio_rate(rdev); 405 - int bps = r600_audio_bits_per_sample(rdev); 406 - uint8_t status_bits = r600_audio_status_bits(rdev); 407 - uint8_t category_code = r600_audio_category_code(rdev); 408 - 409 403 uint32_t iec; 410 404 411 405 if (!dig->afmt || !dig->afmt->enabled) ··· 408 414 409 415 DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", 410 416 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped", 411 - channels, rate, bps); 417 + audio.channels, audio.rate, audio.bits_per_sample); 412 418 DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n", 413 - (int)status_bits, (int)category_code); 419 + (int)audio.status_bits, (int)audio.category_code); 414 420 415 421 iec = 0; 416 - if (status_bits & AUDIO_STATUS_PROFESSIONAL) 422 + if (audio.status_bits & AUDIO_STATUS_PROFESSIONAL) 417 423 iec |= 1 << 0; 418 - if (status_bits & AUDIO_STATUS_NONAUDIO) 424 + if (audio.status_bits & AUDIO_STATUS_NONAUDIO) 419 425 iec |= 1 << 1; 420 - if (status_bits & AUDIO_STATUS_COPYRIGHT) 426 + if (audio.status_bits & AUDIO_STATUS_COPYRIGHT) 421 427 iec |= 1 << 2; 422 - if (status_bits & AUDIO_STATUS_EMPHASIS) 428 + if (audio.status_bits & AUDIO_STATUS_EMPHASIS) 423 429 iec |= 1 << 3; 424 430 425 - iec |= HDMI0_60958_CS_CATEGORY_CODE(category_code); 431 + iec |= HDMI0_60958_CS_CATEGORY_CODE(audio.category_code); 426 432 427 - switch (rate) { 433 + switch (audio.rate) { 428 434 case 32000: 429 435 iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x3); 430 436 break; ··· 451 457 WREG32(HDMI0_60958_0 + offset, iec); 452 458 453 459 iec = 0; 454 - switch (bps) { 460 + switch (audio.bits_per_sample) { 455 461 case 16: 456 462 iec |= HDMI0_60958_CS_WORD_LENGTH(0x2); 457 463 break; ··· 462 468 iec |= HDMI0_60958_CS_WORD_LENGTH(0xb); 463 469 break; 464 470 } 465 - if (status_bits & AUDIO_STATUS_V) 471 + if (audio.status_bits & AUDIO_STATUS_V) 466 472 iec |= 0x5 << 16; 467 473 WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); 468 474 469 - r600_hdmi_audioinfoframe(encoder, channels - 1, 0, 0, 0, 0, 0, 0, 0); 475 + r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0, 476 + 0); 470 477 471 478 r600_hdmi_audio_workaround(encoder); 472 479 }
+2 -2
drivers/gpu/drm/radeon/radeon.h
··· 1094 1094 int instance); 1095 1095 1096 1096 struct r600_audio { 1097 - bool enabled; 1098 1097 int channels; 1099 1098 int rate; 1100 1099 int bits_per_sample; ··· 1534 1535 int num_crtc; /* number of crtcs */ 1535 1536 struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ 1536 1537 struct mutex vram_mutex; 1537 - struct r600_audio audio; /* audio stuff */ 1538 + bool audio_enabled; 1539 + struct r600_audio audio_status; /* audio stuff */ 1538 1540 struct notifier_block acpi_nb; 1539 1541 /* only one userspace can use Hyperz features or CMASK at a time */ 1540 1542 struct drm_file *hyperz_filp;
+1 -6
drivers/gpu/drm/radeon/radeon_asic.h
··· 356 356 void r600_rlc_stop(struct radeon_device *rdev); 357 357 /* r600 audio */ 358 358 int r600_audio_init(struct radeon_device *rdev); 359 - int r600_audio_tmds_index(struct drm_encoder *encoder); 360 359 void r600_audio_set_clock(struct drm_encoder *encoder, int clock); 361 - int r600_audio_channels(struct radeon_device *rdev); 362 - int r600_audio_bits_per_sample(struct radeon_device *rdev); 363 - int r600_audio_rate(struct radeon_device *rdev); 364 - uint8_t r600_audio_status_bits(struct radeon_device *rdev); 365 - uint8_t r600_audio_category_code(struct radeon_device *rdev); 360 + struct r600_audio r600_audio_status(struct radeon_device *rdev); 366 361 void r600_audio_fini(struct radeon_device *rdev); 367 362 int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); 368 363 void r600_hdmi_update_audio_settings(struct drm_encoder *encoder);