diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-04-20 16:55:21 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-06-03 21:03:15 -0400 |
commit | d38ceaf99ed015f2a0b9af3499791bd3a3daae21 (patch) | |
tree | c8e237ea218e8ed8a5f64c1654fc01fe5d2239cb /drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c | |
parent | 97b2e202fba05b87d720318a6500a337100dab4d (diff) |
drm/amdgpu: add core driver (v4)
This adds the non-asic specific core driver code.
v2: remove extra kconfig option
v3: implement minor fixes from Fengguang Wu
v4: fix cast in amdgpu_ucode.c
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c new file mode 100644 index 000000000000..857ba0897159 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Christian König. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Christian König | ||
25 | */ | ||
26 | #include <linux/hdmi.h> | ||
27 | #include <linux/gcd.h> | ||
28 | #include <drm/drmP.h> | ||
29 | #include <drm/amdgpu_drm.h> | ||
30 | #include "amdgpu.h" | ||
31 | |||
32 | static const struct amdgpu_afmt_acr amdgpu_afmt_predefined_acr[] = { | ||
33 | /* 32kHz 44.1kHz 48kHz */ | ||
34 | /* Clock N CTS N CTS N CTS */ | ||
35 | { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ | ||
36 | { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ | ||
37 | { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ | ||
38 | { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ | ||
39 | { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ | ||
40 | { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ | ||
41 | { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ | ||
42 | { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ | ||
43 | { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ | ||
44 | { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ | ||
45 | }; | ||
46 | |||
47 | |||
48 | /* | ||
49 | * calculate CTS and N values if they are not found in the table | ||
50 | */ | ||
51 | static void amdgpu_afmt_calc_cts(uint32_t clock, int *CTS, int *N, int freq) | ||
52 | { | ||
53 | int n, cts; | ||
54 | unsigned long div, mul; | ||
55 | |||
56 | /* Safe, but overly large values */ | ||
57 | n = 128 * freq; | ||
58 | cts = clock * 1000; | ||
59 | |||
60 | /* Smallest valid fraction */ | ||
61 | div = gcd(n, cts); | ||
62 | |||
63 | n /= div; | ||
64 | cts /= div; | ||
65 | |||
66 | /* | ||
67 | * The optimal N is 128*freq/1000. Calculate the closest larger | ||
68 | * value that doesn't truncate any bits. | ||
69 | */ | ||
70 | mul = ((128*freq/1000) + (n-1))/n; | ||
71 | |||
72 | n *= mul; | ||
73 | cts *= mul; | ||
74 | |||
75 | /* Check that we are in spec (not always possible) */ | ||
76 | if (n < (128*freq/1500)) | ||
77 | printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); | ||
78 | if (n > (128*freq/300)) | ||
79 | printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); | ||
80 | |||
81 | *N = n; | ||
82 | *CTS = cts; | ||
83 | |||
84 | DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", | ||
85 | *N, *CTS, freq); | ||
86 | } | ||
87 | |||
88 | struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock) | ||
89 | { | ||
90 | struct amdgpu_afmt_acr res; | ||
91 | u8 i; | ||
92 | |||
93 | /* Precalculated values for common clocks */ | ||
94 | for (i = 0; i < ARRAY_SIZE(amdgpu_afmt_predefined_acr); i++) { | ||
95 | if (amdgpu_afmt_predefined_acr[i].clock == clock) | ||
96 | return amdgpu_afmt_predefined_acr[i]; | ||
97 | } | ||
98 | |||
99 | /* And odd clocks get manually calculated */ | ||
100 | amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); | ||
101 | amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); | ||
102 | amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); | ||
103 | |||
104 | return res; | ||
105 | } | ||