Rev 2160 | Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2160 | Rev 2997 | ||
---|---|---|---|
Line 21... | Line 21... | ||
21 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: Dave Airlie |
23 | * Authors: Dave Airlie |
24 | * Alex Deucher |
24 | * Alex Deucher |
25 | */ |
25 | */ |
- | 26 | #include |
|
- | 27 | ||
26 | #include "drmP.h" |
28 | #include |
- | 29 | #include |
|
27 | #include "radeon_drm.h" |
30 | #include |
28 | #include "radeon.h" |
31 | #include "radeon.h" |
29 | #include "atom.h" |
32 | #include "atom.h" |
Line -... | Line 33... | ||
- | 33 | ||
- | 34 | extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, |
|
- | 35 | struct i2c_msg *msgs, int num); |
|
- | 36 | extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); |
|
30 | 37 | ||
31 | /** |
38 | /** |
32 | * radeon_ddc_probe |
39 | * radeon_ddc_probe |
33 | * |
40 | * |
34 | */ |
41 | */ |
35 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) |
42 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
36 | { |
43 | { |
37 | u8 out = 0x0; |
44 | u8 out = 0x0; |
38 | u8 buf[8]; |
45 | u8 buf[8]; |
39 | int ret; |
46 | int ret; |
40 | struct i2c_msg msgs[] = { |
47 | struct i2c_msg msgs[] = { |
41 | { |
48 | { |
42 | .addr = 0x50, |
49 | .addr = DDC_ADDR, |
43 | .flags = 0, |
50 | .flags = 0, |
44 | .len = 1, |
51 | .len = 1, |
45 | .buf = &out, |
52 | .buf = &out, |
46 | }, |
53 | }, |
47 | { |
54 | { |
48 | .addr = 0x50, |
55 | .addr = DDC_ADDR, |
49 | .flags = I2C_M_RD, |
56 | .flags = I2C_M_RD, |
50 | .len = 1, |
57 | .len = 8, |
51 | .buf = buf, |
58 | .buf = buf, |
52 | } |
59 | } |
Line 53... | Line -... | ||
53 | }; |
- | |
54 | - | ||
55 | /* Read 8 bytes from i2c for extended probe of EDID header */ |
- | |
56 | if (requires_extended_probe) |
- | |
57 | msgs[1].len = 8; |
60 | }; |
58 | 61 | ||
59 | /* on hw with routers, select right port */ |
62 | /* on hw with routers, select right port */ |
Line 60... | Line 63... | ||
60 | if (radeon_connector->router.ddc_valid) |
63 | if (radeon_connector->router.ddc_valid) |
61 | radeon_router_select_ddc_port(radeon_connector); |
64 | radeon_router_select_ddc_port(radeon_connector); |
62 | 65 | ||
63 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); |
66 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); |
64 | if (ret != 2) |
- | |
65 | /* Couldn't find an accessible DDC on this connector */ |
67 | if (ret != 2) |
66 | return false; |
68 | /* Couldn't find an accessible DDC on this connector */ |
67 | if (requires_extended_probe) { |
69 | return false; |
68 | /* Probe also for valid EDID header |
70 | /* Probe also for valid EDID header |
69 | * EDID header starts with: |
71 | * EDID header starts with: |
70 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
72 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
71 | * Only the first 6 bytes must be valid as |
73 | * Only the first 6 bytes must be valid as |
72 | * drm_edid_block_valid() can fix the last 2 bytes */ |
74 | * drm_edid_block_valid() can fix the last 2 bytes */ |
73 | if (drm_edid_header_is_valid(buf) < 6) { |
75 | if (drm_edid_header_is_valid(buf) < 6) { |
74 | /* Couldn't find an accessible EDID on this |
76 | /* Couldn't find an accessible EDID on this |
75 | * connector */ |
- | |
76 | return false; |
77 | * connector */ |
77 | } |
78 | return false; |
Line 78... | Line 79... | ||
78 | } |
79 | } |
Line 79... | Line 80... | ||
79 | return true; |
80 | return true; |
80 | } |
81 | } |
- | 82 | ||
81 | 83 | /* bit banging i2c */ |
|
82 | /* bit banging i2c */ |
84 | |
83 | 85 | static int pre_xfer(struct i2c_adapter *i2c_adap) |
|
Line 84... | Line 86... | ||
84 | static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) |
86 | { |
Line 135... | Line 137... | ||
135 | 137 | ||
136 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
138 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
Line 137... | Line 139... | ||
137 | WREG32(rec->en_data_reg, temp); |
139 | WREG32(rec->en_data_reg, temp); |
138 | 140 | ||
139 | /* mask the gpio pins for software use */ |
- | |
140 | temp = RREG32(rec->mask_clk_reg); |
- | |
141 | if (lock_state) |
- | |
142 | temp |= rec->mask_clk_mask; |
- | |
143 | else |
141 | /* mask the gpio pins for software use */ |
144 | temp &= ~rec->mask_clk_mask; |
142 | temp = RREG32(rec->mask_clk_reg) | rec->mask_clk_mask; |
Line -... | Line 143... | ||
- | 143 | WREG32(rec->mask_clk_reg, temp); |
|
- | 144 | temp = RREG32(rec->mask_clk_reg); |
|
145 | WREG32(rec->mask_clk_reg, temp); |
145 | |
- | 146 | temp = RREG32(rec->mask_data_reg) | rec->mask_data_mask; |
|
- | 147 | WREG32(rec->mask_data_reg, temp); |
|
- | 148 | temp = RREG32(rec->mask_data_reg); |
|
- | 149 | ||
- | 150 | return 0; |
|
- | 151 | } |
|
- | 152 | ||
- | 153 | static void post_xfer(struct i2c_adapter *i2c_adap) |
|
- | 154 | { |
|
146 | temp = RREG32(rec->mask_clk_reg); |
155 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
- | 156 | struct radeon_device *rdev = i2c->dev->dev_private; |
|
- | 157 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
|
- | 158 | uint32_t temp; |
|
- | 159 | ||
147 | 160 | /* unmask the gpio pins for software use */ |
|
148 | temp = RREG32(rec->mask_data_reg); |
161 | temp = RREG32(rec->mask_clk_reg) & ~rec->mask_clk_mask; |
149 | if (lock_state) |
162 | WREG32(rec->mask_clk_reg, temp); |
150 | temp |= rec->mask_data_mask; |
163 | temp = RREG32(rec->mask_clk_reg); |
151 | else |
164 | |
152 | temp &= ~rec->mask_data_mask; |
165 | temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask; |
Line 153... | Line 166... | ||
153 | WREG32(rec->mask_data_reg, temp); |
166 | WREG32(rec->mask_data_reg, temp); |
Line 207... | Line 220... | ||
207 | val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
220 | val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
208 | val |= data ? 0 : rec->en_data_mask; |
221 | val |= data ? 0 : rec->en_data_mask; |
209 | WREG32(rec->en_data_reg, val); |
222 | WREG32(rec->en_data_reg, val); |
210 | } |
223 | } |
Line 211... | Line -... | ||
211 | - | ||
212 | static int pre_xfer(struct i2c_adapter *i2c_adap) |
- | |
213 | { |
- | |
214 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
- | |
215 | - | ||
216 | radeon_i2c_do_lock(i2c, 1); |
- | |
217 | - | ||
218 | return 0; |
- | |
219 | } |
- | |
220 | - | ||
221 | static void post_xfer(struct i2c_adapter *i2c_adap) |
- | |
222 | { |
- | |
223 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
- | |
224 | - | ||
225 | radeon_i2c_do_lock(i2c, 0); |
- | |
226 | } |
- | |
227 | 224 | ||
Line 228... | Line 225... | ||
228 | /* hw i2c */ |
225 | /* hw i2c */ |
229 | 226 | ||
230 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
227 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
Line 888... | Line 885... | ||
888 | static const struct i2c_algorithm radeon_i2c_algo = { |
885 | static const struct i2c_algorithm radeon_i2c_algo = { |
889 | .master_xfer = radeon_hw_i2c_xfer, |
886 | .master_xfer = radeon_hw_i2c_xfer, |
890 | .functionality = radeon_hw_i2c_func, |
887 | .functionality = radeon_hw_i2c_func, |
891 | }; |
888 | }; |
Line -... | Line 889... | ||
- | 889 | ||
- | 890 | static const struct i2c_algorithm radeon_atom_i2c_algo = { |
|
- | 891 | .master_xfer = radeon_atom_hw_i2c_xfer, |
|
- | 892 | .functionality = radeon_atom_hw_i2c_func, |
|
- | 893 | }; |
|
892 | 894 | ||
893 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
895 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
894 | struct radeon_i2c_bus_rec *rec, |
896 | struct radeon_i2c_bus_rec *rec, |
895 | const char *name) |
897 | const char *name) |
896 | { |
898 | { |
897 | struct radeon_device *rdev = dev->dev_private; |
899 | struct radeon_device *rdev = dev->dev_private; |
898 | struct radeon_i2c_chan *i2c; |
900 | struct radeon_i2c_chan *i2c; |
Line -... | Line 901... | ||
- | 901 | int ret; |
|
- | 902 | ||
- | 903 | /* don't add the mm_i2c bus unless hw_i2c is enabled */ |
|
- | 904 | if (rec->mm_i2c && (radeon_hw_i2c == 0)) |
|
899 | int ret; |
905 | return NULL; |
900 | 906 | ||
901 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
907 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
Line 902... | Line 908... | ||
902 | if (i2c == NULL) |
908 | if (i2c == NULL) |
903 | return NULL; |
909 | return NULL; |
- | 910 | ||
904 | 911 | i2c->rec = *rec; |
|
905 | i2c->rec = *rec; |
912 | i2c->adapter.owner = THIS_MODULE; |
906 | // i2c->adapter.owner = THIS_MODULE; |
913 | i2c->adapter.class = I2C_CLASS_DDC; |
907 | i2c->dev = dev; |
914 | i2c->dev = dev; |
908 | i2c_set_adapdata(&i2c->adapter, i2c); |
915 | i2c_set_adapdata(&i2c->adapter, i2c); |
Line 918... | Line 925... | ||
918 | // ret = i2c_add_adapter(&i2c->adapter); |
925 | // ret = i2c_add_adapter(&i2c->adapter); |
919 | // if (ret) { |
926 | // if (ret) { |
920 | // DRM_ERROR("Failed to register hw i2c %s\n", name); |
927 | // DRM_ERROR("Failed to register hw i2c %s\n", name); |
921 | // goto out_free; |
928 | // goto out_free; |
922 | // } |
929 | // } |
- | 930 | } else if (rec->hw_capable && |
|
- | 931 | radeon_hw_i2c && |
|
- | 932 | ASIC_IS_DCE3(rdev)) { |
|
- | 933 | /* hw i2c using atom */ |
|
- | 934 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
|
- | 935 | "Radeon i2c hw bus %s", name); |
|
- | 936 | i2c->adapter.algo = &radeon_atom_i2c_algo; |
|
- | 937 | // ret = i2c_add_adapter(&i2c->adapter); |
|
- | 938 | // if (ret) { |
|
- | 939 | // DRM_ERROR("Failed to register hw i2c %s\n", name); |
|
- | 940 | // goto out_free; |
|
- | 941 | // } |
|
923 | } else { |
942 | } else { |
924 | /* set the radeon bit adapter */ |
943 | /* set the radeon bit adapter */ |
925 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
944 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
926 | "Radeon i2c bit bus %s", name); |
945 | "Radeon i2c bit bus %s", name); |
927 | i2c->adapter.algo_data = &i2c->algo.bit; |
946 | i2c->adapter.algo_data = &i2c->algo.bit; |
Line 929... | Line 948... | ||
929 | i2c->algo.bit.post_xfer = post_xfer; |
948 | i2c->algo.bit.post_xfer = post_xfer; |
930 | i2c->algo.bit.setsda = set_data; |
949 | i2c->algo.bit.setsda = set_data; |
931 | i2c->algo.bit.setscl = set_clock; |
950 | i2c->algo.bit.setscl = set_clock; |
932 | i2c->algo.bit.getsda = get_data; |
951 | i2c->algo.bit.getsda = get_data; |
933 | i2c->algo.bit.getscl = get_clock; |
952 | i2c->algo.bit.getscl = get_clock; |
934 | i2c->algo.bit.udelay = 20; |
953 | i2c->algo.bit.udelay = 10; |
935 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always |
- | |
936 | * make this, 2 jiffies is a lot more reliable */ |
- | |
937 | i2c->algo.bit.timeout = 2; |
954 | i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ |
938 | i2c->algo.bit.data = i2c; |
955 | i2c->algo.bit.data = i2c; |
939 | ret = i2c_bit_add_bus(&i2c->adapter); |
956 | ret = i2c_bit_add_bus(&i2c->adapter); |
940 | if (ret) { |
957 | if (ret) { |
941 | DRM_ERROR("Failed to register bit i2c %s\n", name); |
958 | DRM_ERROR("Failed to register bit i2c %s\n", name); |
942 | goto out_free; |
959 | goto out_free; |
Line 960... | Line 977... | ||
960 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
977 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
961 | if (i2c == NULL) |
978 | if (i2c == NULL) |
962 | return NULL; |
979 | return NULL; |
Line 963... | Line 980... | ||
963 | 980 | ||
964 | i2c->rec = *rec; |
981 | i2c->rec = *rec; |
965 | // i2c->adapter.owner = THIS_MODULE; |
982 | i2c->adapter.owner = THIS_MODULE; |
966 | i2c->adapter.class = I2C_CLASS_DDC; |
983 | i2c->adapter.class = I2C_CLASS_DDC; |
967 | i2c->dev = dev; |
984 | i2c->dev = dev; |
968 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
985 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
969 | "Radeon aux bus %s", name); |
986 | "Radeon aux bus %s", name); |