Compare commits
1087 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65ba162394 | ||
|
|
84932d86ad | ||
|
|
0dc8dae83d | ||
|
|
5d45c37af3 | ||
|
|
d7d25fb0e8 | ||
|
|
f639a59238 | ||
|
|
775595f234 | ||
|
|
81e002bb8f | ||
|
|
ee11f954bc | ||
|
|
e44c946057 | ||
|
|
2e5635feba | ||
|
|
07fa897d19 | ||
|
|
3dc728147b | ||
|
|
f4ff19a0f0 | ||
|
|
1371a59b64 | ||
|
|
69eaca2fef | ||
|
|
d165a4f143 | ||
|
|
c752107a02 | ||
|
|
a0d587989d | ||
|
|
b8ff8d60ed | ||
|
|
f5609621f4 | ||
|
|
b8d5ef9aac | ||
|
|
3c7b2b4679 | ||
|
|
a7e3c97cc5 | ||
|
|
3bbe7b485a | ||
|
|
44e90288dd | ||
|
|
3d9673dba4 | ||
|
|
c9b2d4590c | ||
|
|
e92d5a0b39 | ||
|
|
7b014bd444 | ||
|
|
2f1717a403 | ||
|
|
5710e61b10 | ||
|
|
acb3468f8b | ||
| b89b199a17 | |||
|
|
9bdc3789b1 | ||
|
|
6c35234d83 | ||
|
|
a05af9efdf | ||
|
|
b23c65e039 | ||
|
|
91ecb92cb6 | ||
|
|
56d2f91778 | ||
|
|
db82eb41f1 | ||
|
|
89da5cd137 | ||
|
|
3745ae0ad7 | ||
|
|
d03ef619fc | ||
|
|
7931378fda | ||
|
|
f705611d81 | ||
|
|
51a64dc292 | ||
|
|
834b4db346 | ||
|
|
d912f84b17 | ||
|
|
955ef786b3 | ||
|
|
74eca8d29f | ||
|
|
0ab61c2f5d | ||
|
|
3d1a1e74fc | ||
|
|
ff022e3fd8 | ||
|
|
f2e792c411 | ||
|
|
ade8b1b629 | ||
|
|
5cb7a30105 | ||
|
|
0226898ca6 | ||
|
|
6c18c6d3a0 | ||
|
|
2131cf28e5 | ||
|
|
07ed9100ad | ||
|
|
4f860a13de | ||
|
|
17a996c852 | ||
|
|
6cec5cc81d | ||
|
|
7fe03ccb57 | ||
|
|
9470f6e097 | ||
|
|
25030c977d | ||
|
|
9fa3e91df1 | ||
|
|
1b6868a022 | ||
|
|
3c09ef7d96 | ||
|
|
b092aa34a2 | ||
|
|
2df36c4abf | ||
|
|
d8f8c0faad | ||
|
|
8d75380caf | ||
|
|
4cb80b2638 | ||
|
|
3d76ee5a5b | ||
|
|
be9e2b43f3 | ||
|
|
944bcba007 | ||
|
|
02fbec18ca | ||
|
|
ea836f1026 | ||
|
|
a730579b19 | ||
|
|
4ad5e0815b | ||
|
|
692d85ec0c | ||
|
|
5753a02a42 | ||
|
|
94ab6bf2f1 | ||
|
|
7438822d17 | ||
|
|
1ed35470d7 | ||
|
|
a54ad6a85f | ||
|
|
a71d8fb541 | ||
|
|
40e696a566 | ||
|
|
6ab2399a1a | ||
|
|
82da211b9b | ||
|
|
3be0aa5c21 | ||
|
|
361dc65fd3 | ||
|
|
77266e66b4 | ||
|
|
31067bd91e | ||
|
|
386c45ca97 | ||
|
|
9d482e5994 | ||
|
|
b482f18957 | ||
|
|
b7c6be3b16 | ||
|
|
3021284b0a | ||
|
|
acc53d676a | ||
|
|
f1c6ce150c | ||
|
|
e275f0a5d1 | ||
|
|
f6697caafb | ||
|
|
3141a1036d | ||
|
|
29efd28b74 | ||
|
|
0c97a9c69c | ||
|
|
1415df25a3 | ||
|
|
c84192cba4 | ||
|
|
bd2b02d953 | ||
|
|
6dc97d69a6 | ||
|
|
86ae39b381 | ||
|
|
32818c107f | ||
|
|
141e5e9d21 | ||
|
|
5b18f6aea9 | ||
|
|
00b249be6f | ||
|
|
54be51b2aa | ||
|
|
fb8dc89b4d | ||
|
|
3f3d1c781a | ||
|
|
ad627e8ccf | ||
|
|
6f9d9ccc76 | ||
|
|
cefa38b9f8 | ||
|
|
bb204a2689 | ||
|
|
56356c8065 | ||
|
|
7c08af0706 | ||
|
|
679064a95f | ||
|
|
487ac2b292 | ||
|
|
e1573dd58e | ||
|
|
f8317039fb | ||
|
|
7bfc5040a8 | ||
|
|
f1e4d83cf0 | ||
|
|
0768664fe0 | ||
|
|
f49c184a7d | ||
|
|
5d270880da | ||
| 31d57b3a45 | |||
|
|
6ed3fc627e | ||
|
|
a1d301efb2 | ||
|
|
7d0bc204c7 | ||
|
|
0671064716 | ||
|
|
a03f69b310 | ||
| ba74256d24 | |||
|
|
9166e950b4 | ||
|
|
c526abcf3e | ||
| 5907e5759e | |||
|
|
80c71dc52a | ||
|
|
76bc83bd66 | ||
|
|
9c55afa3c4 | ||
|
|
e2b2bba7ba | ||
|
|
0be9a1a504 | ||
|
|
77889c54ce | ||
|
|
f7e7dc15e2 | ||
|
|
a371bf6d5a | ||
|
|
fa362db291 | ||
|
|
5be6f93061 | ||
|
|
1d22b242c8 | ||
| 9c944c3c25 | |||
|
|
c24abef1b6 | ||
|
|
5b11f988f5 | ||
|
|
e1b2086036 | ||
|
|
7e149d6d99 | ||
|
|
d2029b5462 | ||
|
|
bd0962c50e | ||
| 5e2872af34 | |||
|
|
5628c096c5 | ||
|
|
63ae919adb | ||
|
|
e2f30062dd | ||
|
|
6e7de80aba | ||
|
|
0ac773ecd9 | ||
|
|
90718434fa | ||
| f5e0b20ca6 | |||
| ee45105438 | |||
| 104d540920 | |||
|
|
5f10b7db0c | ||
|
|
c7e2fad919 | ||
|
|
21cae2cddf | ||
|
|
638b68c7e2 | ||
|
|
a483e0ffe6 | ||
| 4dc0da3469 | |||
| 7a10b5ed51 | |||
| 944f2a9b14 | |||
|
|
8106f1fe2c | ||
|
|
453e56f624 | ||
| ce8f04acdb | |||
| 11771c85cf | |||
| eeaf474a79 | |||
|
|
5bdf2ad9db | ||
|
|
f49b051211 | ||
| 939f824d96 | |||
| aef7c5284b | |||
| 43ecc0b6a4 | |||
| 805a23b544 | |||
|
|
4cc87fbe7d | ||
|
|
e8b3efcc2d | ||
|
|
0d893d8b84 | ||
|
|
7923c9765d | ||
|
|
7e3b4f9643 | ||
| 36b358a358 | |||
| 21c3bf8d69 | |||
|
|
5be9290389 | ||
|
|
0df8accb94 | ||
|
|
a06f8cc84c | ||
|
|
34c30dea68 | ||
| 31f5bf31ed | |||
|
|
07cb3855b0 | ||
|
|
42ea13c96b | ||
|
|
553563167c | ||
|
|
4ac08fc6e9 | ||
|
|
13ea3979bb | ||
| abb25d18e9 | |||
| 75110b9fa0 | |||
| ff699eaffc | |||
| e80aaced2b | |||
| f703792c6e | |||
| c3c10da1af | |||
| f188b83bd4 | |||
| c136642c67 | |||
| 069cad1deb | |||
| e119dfaa2f | |||
|
|
072729a7f2 | ||
|
|
d43e578cc8 | ||
|
|
3facc87a41 | ||
|
|
a884725d26 | ||
|
|
7ea36b4316 | ||
|
|
5332de88d9 | ||
|
|
22720e823e | ||
|
|
bbf8c5f14d | ||
|
|
09b06cee2f | ||
|
|
1af612e4d2 | ||
|
|
5847ff53fc | ||
|
|
e22da872c9 | ||
|
|
45f369f418 | ||
|
|
c58b0535f6 | ||
|
|
c01a33cfa5 | ||
|
|
a26689b104 | ||
|
|
9ec5779194 | ||
|
|
01bb499fab | ||
|
|
4589f3ae78 | ||
|
|
931d4df6c1 | ||
|
|
9ad23608e6 | ||
|
|
54e9661045 | ||
|
|
2d73c440b4 | ||
| 5775f44b56 | |||
| f132dd4b48 | |||
| aaf3c424a7 | |||
| 6ec2b20b1c | |||
| eccabfe942 | |||
| 6a5da3cc93 | |||
| a35fe30846 | |||
| e690f0cc4d | |||
|
|
53f90bca38 | ||
|
|
7470652b79 | ||
|
|
7bc0071f59 | ||
|
|
929c2fa683 | ||
|
|
5c194bbe10 | ||
|
|
c6b57fbd1a | ||
|
|
ef9256f6b0 | ||
|
|
da448a7a84 | ||
|
|
cb4549795b | ||
|
|
b7083f5742 | ||
|
|
3f22b06b9f | ||
|
|
bc6cebbf4b | ||
|
|
5a66f7d299 | ||
|
|
4f001bcf95 | ||
|
|
ebd406a2e7 | ||
|
|
673a89c327 | ||
|
|
a97b422321 | ||
|
|
869e8cdf52 | ||
|
|
b3fee1b5e7 | ||
|
|
e50ee3e947 | ||
|
|
fb3e9a2b66 | ||
|
|
037ab747c1 | ||
|
|
3a8ae3d4cb | ||
|
|
b94939c0dc | ||
|
|
38b4e9b960 | ||
|
|
07b6a39a9e | ||
|
|
5620ba7561 | ||
|
|
2c7ef5e739 | ||
|
|
637784b2c1 | ||
|
|
ad6f92b5b9 | ||
|
|
2860a7433c | ||
|
|
23f7fb6f1c | ||
|
|
639d436580 | ||
|
|
6cb566cf5e | ||
|
|
0e79d8c724 | ||
|
|
d08f862229 | ||
|
|
f806f6b7f8 | ||
|
|
d10c087a12 | ||
|
|
2b91637d4d | ||
|
|
67aca9ac45 | ||
|
|
2b13a4a53d | ||
|
|
a881989d7c | ||
|
|
06eb2f3614 | ||
|
|
e7779275eb | ||
|
|
c547e213e8 | ||
|
|
abf7f61fb0 | ||
|
|
4637e1f6a3 | ||
|
|
bdd8453ba4 | ||
|
|
c6d4df748c | ||
|
|
7cb2a21b33 | ||
|
|
ebacfa0899 | ||
|
|
94030d053e | ||
|
|
94aed463d5 | ||
|
|
2769f0fd61 | ||
|
|
28b0948e61 | ||
|
|
059b851217 | ||
|
|
b2e313b0d9 | ||
|
|
3a719cd911 | ||
|
|
0490e63747 | ||
|
|
1146b67279 | ||
|
|
2a2b5a8ff8 | ||
|
|
fca4378433 | ||
|
|
a37530d3dc | ||
|
|
93caed27c6 | ||
|
|
94e7e92eb7 | ||
|
|
e1f26406b7 | ||
|
|
cd1b4f52db | ||
|
|
4533639793 | ||
|
|
a4d9a318f2 | ||
|
|
710a7a5b8b | ||
|
|
a3f173ceb4 | ||
|
|
4def1db832 | ||
|
|
a59b895ca6 | ||
|
|
c6fefc9917 | ||
|
|
1827396bcc | ||
|
|
7079b013bb | ||
|
|
3dac4b35a4 | ||
|
|
c6b94086d8 | ||
|
|
ed2e35a24c | ||
|
|
e5ba650fda | ||
|
|
947f48e392 | ||
|
|
e3f6e939d2 | ||
|
|
0c807b742c | ||
|
|
c1fce6235d | ||
|
|
7e4b227ec1 | ||
|
|
17e3dfb91d | ||
|
|
ad395f70dd | ||
|
|
9040dc17ec | ||
|
|
37d1685bad | ||
|
|
c8bb74ecc2 | ||
|
|
ea1a682e65 | ||
|
|
3e4779ce20 | ||
|
|
0ce1599841 | ||
|
|
19c4a500e9 | ||
|
|
052092663c | ||
|
|
77a4ede567 | ||
|
|
e080f21757 | ||
|
|
a1cf173d09 | ||
|
|
ba3e90bdec | ||
|
|
8322617480 | ||
|
|
bb6bf261e7 | ||
|
|
cc1adaa2dd | ||
|
|
8ca0210b13 | ||
|
|
16b20de954 | ||
|
|
1fe26ef9de | ||
|
|
c69afcb005 | ||
|
|
5d19dd9dc0 | ||
|
|
350d7e1cc7 | ||
|
|
2dae596c61 | ||
|
|
890388b50c | ||
|
|
c4be8acc8c | ||
|
|
8dffd5ba5f | ||
|
|
02fc4154be | ||
|
|
90a098b648 | ||
|
|
0d87986066 | ||
|
|
c669e7bd89 | ||
|
|
b384868a4d | ||
|
|
c521e1fc73 | ||
|
|
80346e52bc | ||
|
|
782a591d6e | ||
|
|
d56898824a | ||
|
|
ad7f978e81 | ||
|
|
50724bd885 | ||
|
|
66658538e4 | ||
|
|
b38aa8a9e9 | ||
|
|
2cfd028b83 | ||
|
|
5cbcda1b2d | ||
|
|
b9e5a9d227 | ||
|
|
07985443ea | ||
|
|
88d5b111cd | ||
|
|
e5d49b5269 | ||
|
|
b9272bd614 | ||
|
|
8d83c4684d | ||
|
|
70dc0ef970 | ||
|
|
5780544c0f | ||
|
|
a5131135c4 | ||
|
|
119066a890 | ||
|
|
b6f863a2e2 | ||
|
|
064055e18f | ||
|
|
6094221d05 | ||
|
|
e461a53e3d | ||
|
|
251159e3c5 | ||
|
|
a85d73c061 | ||
|
|
1ab9baa0a6 | ||
|
|
89e64cc63e | ||
|
|
bda889fba8 | ||
|
|
eead8d2c64 | ||
|
|
524ca9c4c7 | ||
|
|
7e8910b7fe | ||
|
|
b9b45d733a | ||
|
|
e97775cadc | ||
|
|
89d030e950 | ||
|
|
bb54223b35 | ||
|
|
8c335b10b8 | ||
|
|
a7453c4e5b | ||
|
|
b27b500a57 | ||
|
|
a24875d50b | ||
|
|
2c7785b277 | ||
|
|
ff590c086c | ||
|
|
da14e74a6d | ||
|
|
d09388a32f | ||
|
|
9939a10a33 | ||
|
|
061c201f0b | ||
|
|
86aea3e746 | ||
|
|
cf23a1ccc7 | ||
|
|
9a06c513f8 | ||
|
|
11c594dc6e | ||
|
|
9e7e995235 | ||
|
|
44a0814170 | ||
|
|
0ecfb6aa5b | ||
|
|
a73bea0da8 | ||
|
|
26580c8bd1 | ||
|
|
ee2c4f4c94 | ||
|
|
6e65ab7c45 | ||
|
|
9ad47e87ac | ||
|
|
1548de7c2a | ||
|
|
15f607fd64 | ||
|
|
c31385a3f3 | ||
|
|
7bcf433fb8 | ||
|
|
1967c25fac | ||
|
|
9a8b3fd945 | ||
|
|
c3db1855f8 | ||
|
|
7cbaa847fd | ||
|
|
3336ee4f37 | ||
|
|
fde6b79dcc | ||
|
|
723d4d3618 | ||
|
|
54786d007d | ||
|
|
039660a246 | ||
|
|
ebeed28881 | ||
|
|
73451d6086 | ||
|
|
eda7490bf5 | ||
|
|
03ec9a762d | ||
|
|
7602a89157 | ||
|
|
7ad5e56087 | ||
|
|
97918755c2 | ||
|
|
616f769298 | ||
|
|
275695e8c3 | ||
|
|
7941c117bc | ||
|
|
b66406549f | ||
|
|
25713b7524 | ||
|
|
df2ca4bbd5 | ||
|
|
48ecbd9104 | ||
|
|
606f0073f5 | ||
|
|
71f27df7b3 | ||
|
|
76aa52dd6b | ||
|
|
4dbfb6d6a0 | ||
|
|
b4c6fb8d7b | ||
|
|
414e073a1f | ||
|
|
2f33506ce0 | ||
|
|
0074891c6c | ||
|
|
d8ec74dbec | ||
|
|
343ea685ef | ||
|
|
0f35a891d9 | ||
|
|
e02112ea70 | ||
|
|
296ab7feb5 | ||
|
|
748fe8669e | ||
|
|
a3ee7f3740 | ||
|
|
d59aaca0fa | ||
|
|
c2a771d335 | ||
|
|
3ce0c6763b | ||
|
|
51847d89ad | ||
|
|
dc008c6f30 | ||
|
|
21d1027a5a | ||
|
|
814797a829 | ||
|
|
cd14d65fc6 | ||
|
|
e24551e65f | ||
|
|
4f0542fd62 | ||
|
|
4cc19614ca | ||
|
|
f259abc5ff | ||
|
|
17c2ff7b3d | ||
|
|
eec9fdbabb | ||
|
|
bafb2d78f4 | ||
|
|
c1f806239d | ||
|
|
94cec78ecd | ||
|
|
81e27e05e7 | ||
|
|
39d4709d97 | ||
|
|
0ceaac39cf | ||
|
|
0c4aa274bd | ||
|
|
05fad94d49 | ||
|
|
8eaf6e2fcb | ||
|
|
eb7b2475c8 | ||
|
|
a30801ba4b | ||
|
|
8c19251a65 | ||
|
|
01247f1a05 | ||
|
|
07eee4adec | ||
|
|
2fd4568906 | ||
|
|
faa0e12b63 | ||
|
|
0b1eb45cb9 | ||
|
|
9b7b65b014 | ||
|
|
6cdf720037 | ||
|
|
16f5992719 | ||
|
|
38ed47b73c | ||
|
|
b2579e99a5 | ||
|
|
d372427ef3 | ||
|
|
ec5962d52e | ||
|
|
3e571197e0 | ||
|
|
efedbc015e | ||
|
|
67089c784b | ||
|
|
4916376271 | ||
|
|
7bccb7de56 | ||
|
|
b54b752941 | ||
|
|
c499b7de36 | ||
|
|
01d88ae246 | ||
|
|
51662272ac | ||
|
|
5504861649 | ||
|
|
c2d16441b9 | ||
|
|
d7512224b5 | ||
|
|
0313ceaa28 | ||
|
|
84bce0d4d8 | ||
|
|
66417e61bd | ||
|
|
f53429e2f8 | ||
|
|
5aa81d7197 | ||
|
|
b8fa8489d3 | ||
|
|
48a2a652db | ||
|
|
63328e8522 | ||
|
|
2df5588f95 | ||
|
|
73bd1e2963 | ||
|
|
324c641d1a | ||
|
|
6c47c845cb | ||
|
|
d01af144cb | ||
|
|
6b39363987 | ||
|
|
f23fc38433 | ||
|
|
34c712de5d | ||
|
|
3be3768ce0 | ||
|
|
52facee6d5 | ||
|
|
4bfb625f10 | ||
|
|
c38424c343 | ||
|
|
e5c041df96 | ||
|
|
fb3a10620e | ||
|
|
47fe4cff9c | ||
|
|
13095ae856 | ||
|
|
4b5d5984ce | ||
|
|
85028a5147 | ||
|
|
db2f7da2e5 | ||
|
|
7d78d661a3 | ||
|
|
e0479cff91 | ||
|
|
71e4e59cf3 | ||
|
|
3be9554bed | ||
|
|
dd397def14 | ||
|
|
c8f1c5b1ba | ||
|
|
2c856e2fdd | ||
|
|
c0c454e024 | ||
|
|
df6f93e4eb | ||
|
|
c2cb1b6183 | ||
|
|
92f657f440 | ||
|
|
0b0dd3e2c5 | ||
|
|
e954751c46 | ||
|
|
3e7d2e5267 | ||
|
|
1d9fff9e92 | ||
|
|
379dd4d36d | ||
|
|
8df29f7be6 | ||
|
|
a4f10b7565 | ||
|
|
93e2c279ba | ||
|
|
dfac57a317 | ||
|
|
59e4c92d8d | ||
|
|
2199c90dd9 | ||
|
|
b26531da12 | ||
|
|
b229fdc2c2 | ||
|
|
5f63bc470b | ||
|
|
8f49b3612a | ||
|
|
94ec5d65c8 | ||
|
|
268f6d98b7 | ||
|
|
fdab9ee5c7 | ||
|
|
edaf0b8d64 | ||
|
|
a5c7901579 | ||
|
|
6aaa312f13 | ||
|
|
f1bb02a02c | ||
|
|
184e090541 | ||
|
|
390d9aa3a7 | ||
|
|
7651ba5227 | ||
|
|
3880bd7325 | ||
|
|
5ddaca390b | ||
|
|
d2d9121bbf | ||
|
|
1ace6b360e | ||
|
|
d0a2212fb9 | ||
|
|
e83f71a425 | ||
|
|
b0980b5535 | ||
|
|
f2cd6a6d25 | ||
|
|
3be4fd7a4b | ||
|
|
3dad91d3d7 | ||
|
|
d4ed2579d9 | ||
|
|
bdae342131 | ||
|
|
0e12a2072c | ||
|
|
43bd1e645f | ||
|
|
836c97f0ac | ||
|
|
d5f66e011c | ||
|
|
f8ca762192 | ||
|
|
9b1d2c1c51 | ||
|
|
d7d49c0feb | ||
|
|
f6fbed07ac | ||
|
|
251b27b263 | ||
|
|
925adfd15a | ||
|
|
b5bc8a7c09 | ||
|
|
153714889f | ||
|
|
263374dacd | ||
|
|
6a21548368 | ||
|
|
1be3cabb3a | ||
|
|
07486a11e4 | ||
|
|
98a985b7d1 | ||
|
|
7f9f16c0ff | ||
|
|
662b56fa7d | ||
|
|
dea47105d0 | ||
|
|
5154195769 | ||
|
|
87a40b0f48 | ||
|
|
3cd0677d7e | ||
|
|
827172f6c0 | ||
|
|
58a419e855 | ||
|
|
957ae391e2 | ||
|
|
93e66701fb | ||
|
|
5d38105bff | ||
|
|
141e4c2c3d | ||
|
|
6c6a00efd0 | ||
|
|
de8a596226 | ||
|
|
aef3d2908b | ||
|
|
61c54a1be6 | ||
|
|
aa94143ec9 | ||
|
|
4f326f77c6 | ||
|
|
23bdfe5dc4 | ||
|
|
f111d6969f | ||
|
|
eb55d78ee2 | ||
|
|
8c6cbac6a7 | ||
|
|
692d24b4ec | ||
|
|
07aab9f5f6 | ||
|
|
875ba74b27 | ||
|
|
4c1ad6f2c7 | ||
|
|
0b7151a256 | ||
|
|
d018bf5849 | ||
|
|
d2b6b389e4 | ||
|
|
63d41caa25 | ||
|
|
5d5506be1f | ||
|
|
6bca21ea5f | ||
|
|
56299dc76d | ||
|
|
a908d63b4a | ||
|
|
38c388fab5 | ||
|
|
3a9217ff57 | ||
|
|
5d1134a0a8 | ||
|
|
59eaa9f2bd | ||
|
|
fef3689506 | ||
|
|
69160c350e | ||
|
|
8390a01a58 | ||
|
|
91e30473ed | ||
|
|
f7e118aec3 | ||
|
|
a469f3f7e8 | ||
|
|
ba74e7f00f | ||
|
|
ed1742523e | ||
|
|
a6764896b9 | ||
|
|
59af2cd6af | ||
|
|
189a524abf | ||
|
|
4a8392eb9d | ||
|
|
e1f463adf0 | ||
|
|
981a4ac300 | ||
|
|
e9dcca24f4 | ||
|
|
4daae89053 | ||
|
|
0f7aa4d574 | ||
|
|
b192d9260a | ||
|
|
9104b5cebc | ||
|
|
4847853673 | ||
|
|
5fce3b3c95 | ||
|
|
510a108c5d | ||
|
|
dffe2cce57 | ||
|
|
2432006d40 | ||
|
|
4869fa5f70 | ||
|
|
0169b4ea01 | ||
|
|
06a1a8f6a3 | ||
|
|
441fcf143a | ||
|
|
0cca9c7b8c | ||
|
|
614fe2dab1 | ||
|
|
fd4f9bc59f | ||
|
|
db5fd1e74a | ||
|
|
016062e7e6 | ||
|
|
69252dd603 | ||
|
|
17dcdac5d8 | ||
|
|
fef69aab20 | ||
|
|
4c272bed81 | ||
|
|
e26acbd106 | ||
|
|
8101a2af97 | ||
|
|
dd4bac7d4f | ||
|
|
0be85b335e | ||
|
|
73baea5f6c | ||
|
|
1bc5430ccc | ||
|
|
b4c4da41b5 | ||
|
|
298b39f497 | ||
|
|
0305115a3b | ||
|
|
1db510e6a9 | ||
|
|
4048aef3a0 | ||
|
|
ff25566286 | ||
|
|
948040d206 | ||
|
|
76f2b62b94 | ||
|
|
3e1c43afe7 | ||
|
|
1408306a87 | ||
|
|
92829c00bb | ||
|
|
1cf4d04ae9 | ||
|
|
46c7cf52d9 | ||
|
|
cf69f09b47 | ||
|
|
6753d88bae | ||
|
|
5dc5a99124 | ||
|
|
1b3a66fd7b | ||
|
|
4a8a139540 | ||
|
|
405250c8e2 | ||
|
|
f72fabb279 | ||
|
|
54dc123015 | ||
|
|
025b91fede | ||
|
|
7ca193f613 | ||
|
|
c58d3fcbd1 | ||
|
|
84fe57af51 | ||
|
|
13c87af9d3 | ||
|
|
5b119159d4 | ||
|
|
b26a2baf38 | ||
|
|
e779187e24 | ||
|
|
0e065d64a6 | ||
|
|
e449a2473e | ||
|
|
6f7428a7e4 | ||
|
|
21e4bc0233 | ||
|
|
3a44857930 | ||
|
|
ba0dd03fbe | ||
|
|
b58d7cd6e6 | ||
|
|
139ea3d0ee | ||
|
|
b1101aa868 | ||
|
|
5f84f102c5 | ||
|
|
4c9dc158c8 | ||
|
|
ef977fdf26 | ||
|
|
d4db051a61 | ||
|
|
5efd9e7bcf | ||
|
|
2a81124ad8 | ||
|
|
8670b710f7 | ||
|
|
391818d48f | ||
|
|
375088cf8f | ||
|
|
e7b5998b96 | ||
|
|
587a5061c9 | ||
|
|
40f80f0302 | ||
|
|
a8971e7f3a | ||
|
|
32d40918ac | ||
|
|
2ff588abea | ||
|
|
049540fbaf | ||
|
|
e652fe540f | ||
|
|
03d5be2191 | ||
|
|
e0c5415aa5 | ||
|
|
907e29249b | ||
|
|
052bff4128 | ||
|
|
f1bec30fb2 | ||
|
|
9431abc950 | ||
|
|
ce8943dff7 | ||
|
|
ed47d8bf86 | ||
|
|
87fc474bee | ||
|
|
ecc2925f76 | ||
|
|
9bdd298848 | ||
|
|
a9a7e05fb6 | ||
|
|
fd8f50d23f | ||
|
|
3764b8d630 | ||
|
|
9140ef0cce | ||
|
|
f591baba3e | ||
|
|
dfb6c4b5a7 | ||
|
|
dddc5bbf2d | ||
|
|
8a1c0404e2 | ||
|
|
c47aceb21f | ||
|
|
743dc85bed | ||
|
|
1ced1382c9 | ||
|
|
a90d0cfe1d | ||
|
|
04929cf017 | ||
|
|
73c568fb03 | ||
|
|
02bcaaab53 | ||
|
|
6cf25c8bd8 | ||
|
|
b07dfce332 | ||
|
|
72fe949f6f | ||
|
|
6e47c89546 | ||
|
|
21dcb2539a | ||
|
|
97537d56b2 | ||
|
|
161e2aa725 | ||
|
|
d7c8e47442 | ||
|
|
cdfbfc7683 | ||
|
|
ea06a9a084 | ||
|
|
d6e3a434c1 | ||
|
|
c3f06c82fb | ||
|
|
b000e7656d | ||
|
|
0f0c0aabfa | ||
|
|
8df9a500b6 | ||
|
|
77a1a73554 | ||
|
|
352f992fea | ||
|
|
3a9b8fb8f9 | ||
|
|
fb5ddafbe5 | ||
|
|
ee29610808 | ||
|
|
45d720c0c7 | ||
|
|
95ecd429a8 | ||
|
|
b0776c09ad | ||
|
|
fcf5e6d6b9 | ||
|
|
3ad5b727b9 | ||
|
|
916724d2cd | ||
|
|
de2dc3ecef | ||
|
|
d8eaebacbf | ||
|
|
2f5bd288b7 | ||
|
|
0502a61207 | ||
|
|
76d3050df9 | ||
|
|
1aafb8c866 | ||
|
|
de9db47e0a | ||
|
|
271a1c2ecd | ||
|
|
3ea0750ebe | ||
|
|
579829b9f9 | ||
|
|
cc80eeaa07 | ||
|
|
5b0eb8ab98 | ||
|
|
db4ac47e56 | ||
|
|
979e9112da | ||
|
|
ef27b83e97 | ||
|
|
21572e62ae | ||
|
|
075c0ea71a | ||
|
|
c682e2d8c0 | ||
|
|
a89bf95159 | ||
|
|
13528c5c97 | ||
|
|
b661da340a | ||
|
|
82fe412a09 | ||
|
|
5a467f60e3 | ||
|
|
dfe81eb28d | ||
|
|
a79e7c4171 | ||
|
|
3111c3f230 | ||
|
|
0989244bd5 | ||
|
|
a6c8d276c3 | ||
|
|
5121a68d46 | ||
|
|
1ace68286b | ||
|
|
5756e1bfc8 | ||
|
|
8d88fe9531 | ||
|
|
577eed1321 | ||
|
|
4256086104 | ||
|
|
f2647d013c | ||
|
|
71974025fe | ||
|
|
822a9715c4 | ||
|
|
e7d381a4b4 | ||
|
|
2c4d922032 | ||
|
|
f050c18f32 | ||
|
|
c5afda25bd | ||
|
|
487569711c | ||
|
|
7038d7bc41 | ||
|
|
a17b90b7b3 | ||
|
|
e7be690de5 | ||
|
|
dbd82dd523 | ||
|
|
254c631866 | ||
|
|
d51f1259a0 | ||
|
|
d1b95f89ef | ||
|
|
b5e0fe41ca | ||
|
|
0e85b8f362 | ||
|
|
c40426acda | ||
|
|
e15c3449f3 | ||
|
|
b542bfb588 | ||
|
|
c3a36dffbc | ||
|
|
94747a3d1a | ||
|
|
3f37e88368 | ||
|
|
73aa6c6d6a | ||
|
|
72cb45f7f1 | ||
|
|
98348199e8 | ||
|
|
da76b9b73a | ||
|
|
aef32ec859 | ||
|
|
6cda8bcecd | ||
|
|
ad7724b20b | ||
|
|
a646a65def | ||
|
|
6ab013ea0b | ||
|
|
5462727f9c | ||
|
|
b1fda0395c | ||
|
|
983c7036a5 | ||
|
|
15170454cc | ||
|
|
c6080c59e9 | ||
|
|
14256358ea | ||
|
|
f825a71d89 | ||
|
|
a9706fb6ca | ||
|
|
1e7402569a | ||
|
|
55ed9e2720 | ||
|
|
1db135d09c | ||
|
|
7cae037e85 | ||
|
|
0cb93396cf | ||
|
|
b9300edb72 | ||
|
|
d6ffa8cd02 | ||
|
|
2f3e0a30ee | ||
|
|
62f0273742 | ||
|
|
da2d1b6055 | ||
|
|
fd12438007 | ||
|
|
18334aa2f8 | ||
|
|
49830b7fd4 | ||
|
|
dd99e0d71a | ||
|
|
3fd82557ce | ||
|
|
853d0ada7d | ||
|
|
7fe01d3053 | ||
|
|
ce67c673a0 | ||
|
|
82ef5da45f | ||
|
|
acc759e3d8 | ||
|
|
b308bbdde7 | ||
|
|
af99f0b88d | ||
|
|
f5b902bbee | ||
|
|
d40f7261aa | ||
|
|
63e2b216d4 | ||
|
|
016250f984 | ||
|
|
9d8d99d478 | ||
|
|
c0f513c3db | ||
|
|
62564c56b0 | ||
|
|
88e9e4be91 | ||
|
|
08a4dc7f2d | ||
|
|
c4329e6227 | ||
|
|
6ec45316ae | ||
|
|
b22c241723 | ||
|
|
3a022d4441 | ||
|
|
e85c475db0 | ||
|
|
c30932c83e | ||
|
|
0575dbf098 | ||
|
|
a337842d61 | ||
|
|
54e1aacfec | ||
|
|
46d4105bf9 | ||
|
|
79e75903db | ||
|
|
2a4b34f171 | ||
|
|
d510d16f49 | ||
|
|
1ad99d565b | ||
|
|
62c4becf44 | ||
|
|
01056f99f2 | ||
|
|
1c9a42e362 | ||
|
|
86db9e1fc4 | ||
|
|
36ae3b7991 | ||
|
|
94294b0b80 | ||
|
|
7d89df5d1b | ||
|
|
077f779dea | ||
|
|
8871a59fcf | ||
|
|
b648a77792 | ||
|
|
7f38fb4c37 | ||
|
|
eefd849556 | ||
|
|
0d0ebf947b | ||
|
|
4b390b8b1a | ||
|
|
957f33b4ba | ||
|
|
e1c5ec4c11 | ||
|
|
1391dd1d1d | ||
|
|
00b8fb388c | ||
|
|
44a74d9138 | ||
|
|
f96c2c867c | ||
|
|
763bc3ad70 | ||
|
|
fa83bf6c24 | ||
|
|
ca9c99d8c9 | ||
|
|
9e37e39a22 | ||
|
|
4584e8c2df | ||
|
|
7c1c3a07a8 | ||
|
|
3eda462807 | ||
|
|
e7139a65a7 | ||
|
|
c6d6567ec3 | ||
|
|
4b73c68fff | ||
|
|
c9a1b11964 | ||
|
|
ed2a996944 | ||
|
|
f5c7d5551c | ||
|
|
40b1c24dc3 | ||
|
|
7206330557 | ||
|
|
8e9cf5aa3a | ||
|
|
ae5e114234 | ||
|
|
ef2a2e0e6a | ||
|
|
1668ac9032 | ||
|
|
be5ccc0bc1 | ||
|
|
1d515a0c77 | ||
|
|
4708579954 | ||
|
|
ad550e216e | ||
|
|
ad55c9aee2 | ||
|
|
7d1826758e | ||
|
|
85aa5c3167 | ||
|
|
5e5bb72582 | ||
|
|
ddb7a72c8b | ||
|
|
fc4d6ab4af | ||
|
|
b4dd0c152f | ||
|
|
aacb4b7591 | ||
|
|
7c8ba5ff40 | ||
|
|
f9f3d06971 | ||
|
|
95366971d1 | ||
|
|
5a16823ef7 | ||
|
|
bed870101d | ||
|
|
ab3caba8a7 | ||
|
|
de97cea06c | ||
|
|
e60d47ae50 | ||
|
|
174a707452 | ||
|
|
8609e45095 | ||
|
|
9395f92693 | ||
|
|
6c854695d0 | ||
|
|
233c3e6435 | ||
|
|
6f8abcc3e7 | ||
|
|
ec7c8397d5 | ||
|
|
1634ac97c2 | ||
|
|
b6950333ac | ||
|
|
0e39a3fffe | ||
|
|
2e850e52f6 | ||
|
|
603863d00c | ||
|
|
393a43c2ba | ||
|
|
4d719e6bc5 | ||
|
|
6127c7381d | ||
|
|
69e4361cc8 | ||
|
|
b239f46ecb | ||
|
|
1e0680aa80 | ||
|
|
7f1f402a78 | ||
|
|
2665e9eebc | ||
|
|
bede2c62e6 | ||
|
|
cfec947b3a | ||
|
|
18c3550908 | ||
|
|
94b3a5b74e | ||
|
|
58ea327b12 | ||
|
|
990e3f745c | ||
|
|
87aca91906 | ||
|
|
51d395d0cc | ||
|
|
7df9c18621 | ||
|
|
55d060c456 | ||
|
|
7e19914ef4 | ||
|
|
1eba0190d0 | ||
|
|
bb515acb25 | ||
|
|
d3ae4b4e07 | ||
|
|
c32993d622 | ||
|
|
d37931f10a | ||
|
|
334f7721de | ||
|
|
65cbed8f0d | ||
|
|
dde2612191 | ||
|
|
ec76c66cd2 | ||
|
|
8df5cba38d | ||
|
|
16091ddd9e | ||
|
|
b573c43d09 | ||
|
|
e3172037f7 | ||
|
|
19bd066c8c | ||
|
|
10aa08b39b | ||
|
|
c0ef030710 | ||
|
|
615d8e83ab | ||
|
|
5551095432 | ||
|
|
fdae3a8463 | ||
|
|
11c04adbbc | ||
|
|
857f757f85 | ||
|
|
28e25be617 | ||
|
|
df2e1aa3a9 | ||
|
|
d99e3ea921 | ||
|
|
5638fe22ff | ||
|
|
bf63dda480 | ||
|
|
3e2bc5b35f | ||
|
|
9a27b206b3 | ||
|
|
7a1e29cbc9 | ||
|
|
849b393cad | ||
|
|
fca11d7700 | ||
|
|
f9a3eb973f | ||
|
|
630234432f | ||
|
|
5aa9386dcc | ||
|
|
bbc7ddcf4f | ||
|
|
07ff3f1978 | ||
|
|
82859246df | ||
|
|
45e9240e92 | ||
|
|
16e3ab15b2 | ||
|
|
c5b30426a8 | ||
|
|
ad532cdbaa | ||
|
|
d925b54ad5 | ||
|
|
ad6d923147 | ||
|
|
251420e666 | ||
|
|
400f8f145d | ||
|
|
0727181583 | ||
|
|
548cefab68 | ||
|
|
497393b8cb | ||
|
|
e44a4705bc | ||
|
|
56d23ae060 | ||
|
|
c1783c769f | ||
|
|
3ac6e40242 | ||
|
|
6cc0b12acb | ||
|
|
b429107fec | ||
|
|
4a1560020b | ||
|
|
b3a457d97d | ||
|
|
62da2ad490 | ||
|
|
8c3875e438 | ||
|
|
1e5f55f29c | ||
|
|
26d6c6af0e | ||
|
|
858db1a8a3 | ||
|
|
cb6852bc2c | ||
|
|
65a732dc5a | ||
|
|
60290f1452 | ||
|
|
0b65f18e93 | ||
|
|
c9d4558817 | ||
|
|
17da7e7f7a | ||
|
|
9d76fed06e | ||
|
|
a939e78130 | ||
|
|
0d97209173 | ||
|
|
7c7f68ee6f | ||
|
|
12ecff7fb2 | ||
|
|
7e96e14297 | ||
|
|
09f8067f56 | ||
|
|
d3d3fc15c6 | ||
|
|
aa7be4e6f1 | ||
|
|
9b016cea47 | ||
|
|
f08ff6ca70 | ||
|
|
5db3c3adc1 | ||
|
|
e9e0059192 | ||
|
|
03b4d7367e |
37
drivers/audio/a5536/geode.asm
Normal file
37
drivers/audio/a5536/geode.asm
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
use32
|
||||
|
||||
db 'MENUET01'
|
||||
dd 1
|
||||
dd start
|
||||
dd i_end
|
||||
dd mem
|
||||
dd mem
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
start:
|
||||
mov eax, 68
|
||||
mov ebx, 16
|
||||
mov ecx, sz_sound
|
||||
int 0x40
|
||||
test eax, eax
|
||||
jnz .exit
|
||||
|
||||
mov eax, 68
|
||||
mov ebx, 21
|
||||
mov ecx, sz_path
|
||||
int 0x40
|
||||
|
||||
.exit:
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
|
||||
sz_sound db 'SOUND',0
|
||||
sz_path db '/rd/1/drivers/geode.drv',0
|
||||
|
||||
align 4
|
||||
i_end:
|
||||
rb 128
|
||||
mem:
|
||||
3
drivers/audio/a5536/geode.bat
Normal file
3
drivers/audio/a5536/geode.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
del geode.dll
|
||||
make
|
||||
@pause
|
||||
560
drivers/audio/a5536/geode.c
Normal file
560
drivers/audio/a5536/geode.c
Normal file
@@ -0,0 +1,560 @@
|
||||
|
||||
|
||||
#define FORCED_PIO
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "pci.h"
|
||||
#include "syscall.h"
|
||||
|
||||
#include "geode.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(format,...) dbgprintf(format,##__VA_ARGS__)
|
||||
#else
|
||||
#define DBG(format,...)
|
||||
#endif
|
||||
|
||||
#define BM0_IRQ 0x04
|
||||
#define BM1_IRQ 0x08
|
||||
#define BITS_8_TO_16(x) ( ( (long) ((unsigned char) x - 128) ) << 8 )
|
||||
|
||||
#define PCI_VENDOR_ID_NS 0x100b
|
||||
#define PCI_VENDOR_ID_AMD 0x1022
|
||||
|
||||
|
||||
#ifndef PCI_DEVICE_ID_NS_CS5535_AUDIO
|
||||
#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_AMD_CS5536_AUDIO
|
||||
#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
|
||||
#endif
|
||||
|
||||
#define ID_DEV_1 ((PCI_DEVICE_ID_NS_CS5535_AUDIO << 16)|PCI_VENDOR_ID_NS)
|
||||
#define ID_DEV_2 ((PCI_DEVICE_ID_AMD_CS5536_AUDIO << 16)|PCI_VENDOR_ID_AMD)
|
||||
|
||||
#define SET 1
|
||||
#define CLEAR 0
|
||||
|
||||
int __stdcall srv_sound(ioctl_t *io);
|
||||
|
||||
|
||||
PRD_ENTRY __attribute__((aligned(16))) prd_tab[5];
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PCITAG pciTag;
|
||||
Bool is_iomapped;
|
||||
addr_t F3BAR0;
|
||||
|
||||
Bool fAD1819A;
|
||||
|
||||
int CurrentPowerState;
|
||||
|
||||
addr_t buffer;
|
||||
addr_t prd_dma;
|
||||
|
||||
addr_t irq_line;
|
||||
u32_t irq_mask;
|
||||
|
||||
void __stdcall (*callback)(addr_t buffer);
|
||||
}geode_t;
|
||||
|
||||
geode_t geode;
|
||||
|
||||
|
||||
static inline void ctrl_write_32(addr_t reg, u32_t data)
|
||||
{
|
||||
reg+= geode.F3BAR0;
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
out32((u16_t)reg, data);
|
||||
#else
|
||||
if(geode.is_iomapped)
|
||||
out32((u16_t)reg, data);
|
||||
else
|
||||
*(u32_t*)reg = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u32_t ctrl_read_32(addr_t reg)
|
||||
{
|
||||
reg+= geode.F3BAR0;
|
||||
#ifdef FORCED_PIO
|
||||
return in32((u16_t)reg);
|
||||
#else
|
||||
if(geode.is_iomapped)
|
||||
return in32((u16_t)reg);
|
||||
else
|
||||
return *(u32_t*)reg;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bool snd_hw_WaitForBit(addr_t offset, u32_t Bit,
|
||||
unsigned char Operation,
|
||||
count_t timeout,
|
||||
u32_t *pReturnValue)
|
||||
{
|
||||
volatile u32_t tmp;
|
||||
|
||||
tmp = ctrl_read_32(offset);
|
||||
|
||||
while (timeout)
|
||||
{
|
||||
if (Operation==CLEAR){
|
||||
if (!(tmp & Bit))
|
||||
break;
|
||||
} else if (tmp & Bit)
|
||||
break;
|
||||
|
||||
/*If the Bit is not clear yet, we wait for 10 milisecond and try again*/
|
||||
delay(10/10);
|
||||
|
||||
tmp = ctrl_read_32(offset);
|
||||
|
||||
timeout--;
|
||||
};
|
||||
|
||||
if (pReturnValue)
|
||||
*pReturnValue=tmp;
|
||||
|
||||
if (!timeout)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u16_t snd_hw_CodecRead ( u8_t CodecRegister )
|
||||
{
|
||||
u32_t CodecRegister_data = 0;
|
||||
u32_t timeout=10;
|
||||
volatile u32_t val=0;
|
||||
|
||||
CodecRegister_data = ((u32_t)CodecRegister)<<24;
|
||||
CodecRegister_data |= 0x80000000; /* High-bit set (p.106) is a CODEC reg READ.*/
|
||||
|
||||
/* Set the bit. We are going to access the CODEC...*/
|
||||
CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
|
||||
|
||||
/*Request the data*/
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
|
||||
|
||||
/* Now we need to wait for BIT_5535_CODEC_COMMAND_NEW of the Codec control register to clear
|
||||
(For subsequent Reads/Writes)*/
|
||||
if (!snd_hw_WaitForBit (CODEC_CONTROL_REG_5535,
|
||||
BIT_5535_CODEC_COMMAND_NEW, CLEAR, 50, NULL))
|
||||
DBG("BIT_5535_CODEC_COMMAND_NEW did not clear!!\n");
|
||||
|
||||
/* Wait for CODEC_STATUS_NEW and confirm the read of the requested register*/
|
||||
timeout = 50;
|
||||
do
|
||||
{
|
||||
val = ctrl_read_32(CODEC_STATUS_REG_5535);
|
||||
if ((val & BIT_5535_CODEC_STATUS_NEW) &&
|
||||
((u32_t) CodecRegister == ((0xFF000000 & val)>>24)))
|
||||
break;
|
||||
else
|
||||
/*Wait for 10 miliseconds and try again*/
|
||||
delay(10/10);
|
||||
} while ( --timeout);
|
||||
|
||||
if (!timeout)
|
||||
DBG("Could not read the CODEC!! Returning what we got.\n");
|
||||
|
||||
return( (u16_t)val );
|
||||
}
|
||||
|
||||
void snd_hw_CodecWrite( u8_t CodecRegister, u16_t CodecData )
|
||||
{
|
||||
u32_t CodecRegister_data;
|
||||
u32_t Temp, timeout;
|
||||
|
||||
CodecRegister_data = ((u32_t) CodecRegister)<<24;
|
||||
CodecRegister_data |= (u32_t) CodecData;
|
||||
CodecRegister_data &= CODEC_COMMAND_MASK;
|
||||
|
||||
/*Set the bit. We are going to access the CODEC...*/
|
||||
CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
|
||||
|
||||
/*Write the data*/
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
|
||||
//OS_DbgMsg("Writing: %08X\n", CodecRegister_data);
|
||||
|
||||
/*We need to wait for bit16 of the Codec control register to clear*/
|
||||
Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
|
||||
|
||||
timeout = 50;
|
||||
|
||||
while ((Temp & BIT_5535_CODEC_COMMAND_NEW) && timeout-- )
|
||||
Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
|
||||
|
||||
if (!timeout)
|
||||
DBG("Could not Write the CODEC!!\n"
|
||||
"BIT_5535_CODEC_COMMAND_NEW did not clear!\n");
|
||||
}
|
||||
|
||||
|
||||
void snd_hw_SetCodecRate(u32_t SampleRate)
|
||||
{
|
||||
u16_t val;
|
||||
|
||||
DBG("Rate: %d\n", SampleRate);
|
||||
|
||||
/*If Double-Rate is supported (Bit 2 on register 28h)...*/
|
||||
val=snd_hw_CodecRead(EXTENDED_AUDIO_ID);
|
||||
|
||||
if (val & 0x02)
|
||||
{
|
||||
DBG("Codec supports Double rate.\n");
|
||||
val=snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT);
|
||||
|
||||
if (SampleRate>48000)
|
||||
{
|
||||
snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val|0x0002));
|
||||
SampleRate/=2;
|
||||
}
|
||||
else
|
||||
snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val&0xFFFD));
|
||||
}
|
||||
if (geode.fAD1819A)
|
||||
{
|
||||
DBG("AD1819...\n");
|
||||
snd_hw_CodecWrite(AD1819A_PCM_SR0,(u16_t)SampleRate);
|
||||
}
|
||||
else
|
||||
snd_hw_CodecWrite(PCM_FRONT_DAC_RATE,(u16_t)SampleRate);
|
||||
}
|
||||
|
||||
Bool init_device()
|
||||
{
|
||||
u32_t io_base = pciReadLong(geode.pciTag, 0x10);
|
||||
|
||||
if( PCI_MAP_IS_IO(io_base))
|
||||
{
|
||||
geode.is_iomapped = TRUE;
|
||||
geode.F3BAR0 = PCIGETIO(io_base);
|
||||
DBG("io mapped F3BAR0 %x\n", geode.F3BAR0);
|
||||
}
|
||||
else if(PCI_MAP_IS_MEM(io_base))
|
||||
{
|
||||
geode.is_iomapped = FALSE;
|
||||
io_base = PCIGETMEMORY(io_base);
|
||||
geode.F3BAR0 = MapIoMem(io_base, 128, PG_SW+PG_NOCACHE);
|
||||
DBG("memory mapped F3BAR0 %x\n", geode.F3BAR0);
|
||||
}
|
||||
|
||||
geode.buffer = KernelAlloc(64*1024);
|
||||
|
||||
addr_t buffer = geode.buffer;
|
||||
addr_t dma = GetPgAddr(geode.buffer);
|
||||
|
||||
geode.prd_dma = (((addr_t)prd_tab) & 4095) + GetPgAddr((void*)prd_tab);
|
||||
|
||||
prd_tab[0].ulPhysAddr = dma;
|
||||
prd_tab[0].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[1].ulPhysAddr = dma + 16384;
|
||||
prd_tab[1].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[2].ulPhysAddr = dma + 16384*2;
|
||||
prd_tab[2].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[3].ulPhysAddr = dma + 16384*3;
|
||||
prd_tab[3].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[4].ulPhysAddr = geode.prd_dma;
|
||||
prd_tab[4].SizeFlags = PRD_JMP_BIT ;
|
||||
|
||||
ctrl_write_32(0x24, geode.prd_dma);
|
||||
|
||||
__clear((void*)buffer,64*1024);
|
||||
// u32_t tmp = ctrl_read_32(0x24);
|
||||
|
||||
// dbgprintf("Create primary buffer at %x dma at %x\n", geode.buffer, dma );
|
||||
|
||||
// dbgprintf("Set prd dma %x, read prd dma %x\n", geode.prd_dma, tmp);
|
||||
|
||||
geode.irq_line = pciReadLong(geode.pciTag, 0x3C) & 0xFF;
|
||||
geode.irq_mask = ~(1<<geode.irq_line);
|
||||
|
||||
DBG("Irq line %d, mask %x\n", geode.irq_line, geode.irq_mask);
|
||||
|
||||
|
||||
/*
|
||||
geode.CommandRegister = geode.F3BAR0+0x20;
|
||||
geode.PRDTableAddress = geode.F3BAR0+0x24;
|
||||
geode.DMAPointer = geode.F3BAR0+0x60;
|
||||
|
||||
geode.IRQControlRegister = geode.F3BAR0+0x1C;
|
||||
geode.InternalIRQEnableRegister = geode.F3BAR0+0x1A;
|
||||
geode.SMI_StatusRegister = geode.F3BAR0+0x21;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*CODEC - RESET and volumes initalization.*/
|
||||
/*Set the Warm RESET and CODEC_COMMAND_NEW bits.*/
|
||||
|
||||
DBG("reset codec...\n");
|
||||
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, 0x00030000 );
|
||||
|
||||
if (!snd_hw_WaitForBit (CODEC_STATUS_REG_5535, BIT_CODEC_READY, SET, 40, NULL))
|
||||
{
|
||||
DBG("Primary Codec NOT Ready...Aborting\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u16_t id7c, id7e;
|
||||
|
||||
id7c = snd_hw_CodecRead(AD1819A_VENDORID1);
|
||||
id7e = snd_hw_CodecRead(AD1819A_VENDORID2);
|
||||
|
||||
dbgprintf("codec id 0x7C %x 0x7E %x\n", id7c, id7e);
|
||||
|
||||
/*Check which codec is being used */
|
||||
if ( (id7c == 0x4144) &&
|
||||
(id7e == 0x5303) )
|
||||
{
|
||||
geode.fAD1819A = TRUE;
|
||||
/* Enable non-48kHz sample rates. */
|
||||
snd_hw_CodecWrite (AD1819A_SER_CONF,
|
||||
snd_hw_CodecRead(AD1819A_SER_CONF>>8) |
|
||||
AD1819A_SER_CONF_DRQEN);
|
||||
DBG("detect AD1819A audio codec\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
geode.fAD1819A = FALSE;
|
||||
snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT,
|
||||
(snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT) | 0x0001));
|
||||
/* set the VRA bit to ON*/
|
||||
}
|
||||
|
||||
/* set default volume*/
|
||||
snd_hw_CodecWrite( MASTER_VOLUME, 0x0909);
|
||||
snd_hw_CodecWrite( PCM_OUT_VOL, 0x0606);
|
||||
snd_hw_CodecWrite( PC_BEEP_VOLUME, 0x0000);
|
||||
snd_hw_CodecWrite( PHONE_VOLUME, 0x0606);
|
||||
snd_hw_CodecWrite( MIC_VOLUME, 0x8048);
|
||||
snd_hw_CodecWrite( LINE_IN_VOLUME, 0x0808);
|
||||
snd_hw_CodecWrite( CD_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( VIDEO_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( TV_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( RECORD_SELECT, 0x0000);
|
||||
snd_hw_CodecWrite( RECORD_GAIN, 0x0a0a);
|
||||
snd_hw_CodecWrite( GENERAL_PURPOSE, 0x0200);
|
||||
snd_hw_CodecWrite( MASTER_VOLUME_MONO, 0x0000);
|
||||
|
||||
snd_hw_SetCodecRate(48000);
|
||||
/*Set all the power state bits to 0 (Reg 26h)*/
|
||||
snd_hw_CodecWrite (POWERDOWN_CTRL_STAT, 0x0000);
|
||||
geode.CurrentPowerState = GEODEAUDIO_D0;
|
||||
// OS_DbgMsg("<--snd_hw_InitAudioRegs\n");
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int snd_StartDMA ()
|
||||
{
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
|
||||
else
|
||||
*(u8_t*)(geode.F3BAR0+0x20)= PCI_READS | ENABLE_BUSMASTER;
|
||||
#endif
|
||||
return 0;
|
||||
};
|
||||
|
||||
static u8_t snd_hw_InterruptID ()
|
||||
{
|
||||
volatile u8_t *TempInterruptID, ID;
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
|
||||
else
|
||||
{
|
||||
TempInterruptID=(u8_t*)(geode.F3BAR0 + 0x12);
|
||||
ID=*TempInterruptID;
|
||||
}
|
||||
#endif
|
||||
return (ID);
|
||||
}
|
||||
|
||||
|
||||
static u8_t snd_hw_ClearStat(int Channel)
|
||||
{
|
||||
volatile u8_t status; /*Volatile to force read-to-clear.*/
|
||||
|
||||
/*Read to clear*/
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
status = in8((u16_t) geode.F3BAR0 + 0x21);
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
status = in8((u16_t) geode.F3BAR0 + 0x21);
|
||||
else
|
||||
status = *((u8_t*)geode.F3BAR0 + 0x21);
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void snd_interrupt()
|
||||
{
|
||||
u8_t IntID;
|
||||
|
||||
IntID = snd_hw_InterruptID();
|
||||
|
||||
// dbgprintf("IRQ id %x\n", IntID);
|
||||
|
||||
snd_hw_ClearStat(CHANNEL0_PLAYBACK);
|
||||
// snd_hw_ClearStat(CHANNEL1_RECORD);
|
||||
|
||||
if(IntID & BM0_IRQ)
|
||||
{
|
||||
addr_t prd, offset, base;
|
||||
|
||||
prd = ctrl_read_32(0x24);
|
||||
offset = (1 + (prd - geode.prd_dma)>>3) & 3;
|
||||
|
||||
base = geode.buffer + 16384*offset;
|
||||
|
||||
geode.callback(base);
|
||||
__asm__ volatile("":::"ebx","esi","edi");
|
||||
|
||||
// dbgprintf(">>BM0_IRQ prd %x offset %x base %x\n", prd, offset, base);
|
||||
};
|
||||
};
|
||||
|
||||
Bool FindPciDevice()
|
||||
{
|
||||
u32_t bus, last_bus;
|
||||
PCITAG tag;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return FALSE;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
u32_t pciId=0;
|
||||
|
||||
pciId = PciRead32(bus,devfn, 0);
|
||||
|
||||
if( (pciId == ID_DEV_1) ||
|
||||
(pciId == ID_DEV_2) )
|
||||
{
|
||||
DBG("detect companion audio device %x\n", pciId);
|
||||
geode.pciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
return TRUE;
|
||||
};
|
||||
};
|
||||
};
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int action)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
int i;
|
||||
|
||||
if(action != 1)
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if(!dbg_open("/rd/1/drivers/geode.log"))
|
||||
{
|
||||
printf("Can't open /rd/1/drivers/geode.log\nExit\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FindPciDevice() == FALSE)
|
||||
{
|
||||
DBG("Device not found\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
init_device();
|
||||
|
||||
retval = RegService("SOUND", srv_sound);
|
||||
|
||||
AttachIntHandler(geode.irq_line, snd_interrupt, 0);
|
||||
|
||||
DBG("reg service %s as: %x\n", "SOUND", retval);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
#define API_VERSION 0x01000100
|
||||
|
||||
#define SRV_GETVERSION 0
|
||||
#define DEV_PLAY 1
|
||||
#define DEV_STOP 2
|
||||
#define DEV_CALLBACK 3
|
||||
#define DEV_SET_BUFF 4
|
||||
#define DEV_NOTIFY 5
|
||||
#define DEV_SET_MASTERVOL 6
|
||||
#define DEV_GET_MASTERVOL 7
|
||||
#define DEV_GET_INFO 8
|
||||
|
||||
|
||||
int __stdcall srv_sound(ioctl_t *io)
|
||||
{
|
||||
u32_t *inp;
|
||||
u32_t *outp;
|
||||
|
||||
inp = io->input;
|
||||
outp = io->output;
|
||||
|
||||
switch(io->io_code)
|
||||
{
|
||||
case SRV_GETVERSION:
|
||||
if(io->out_size==4)
|
||||
{
|
||||
*outp = API_VERSION;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEV_PLAY:
|
||||
return snd_StartDMA();
|
||||
break;
|
||||
|
||||
case DEV_STOP:
|
||||
break;
|
||||
|
||||
case DEV_CALLBACK:
|
||||
if(io->inp_size==4)
|
||||
{
|
||||
geode.callback = (void*)(*inp);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PARAM;
|
||||
};
|
||||
return ERR_PARAM;
|
||||
}
|
||||
|
||||
|
||||
200
drivers/audio/a5536/geode.h
Normal file
200
drivers/audio/a5536/geode.h
Normal file
@@ -0,0 +1,200 @@
|
||||
|
||||
|
||||
//
|
||||
// Device and Vendor IDs - Needed like this for OSS only
|
||||
//
|
||||
#define CYRIX_VENDOR_ID 0x1078
|
||||
#define NATIONAL_VENDOR_ID 0x100B
|
||||
|
||||
//
|
||||
// Audio Device IDs
|
||||
//
|
||||
#define CX5530_DEV_ID 0x0103
|
||||
#define SC1200_DEV_ID 0x0503
|
||||
#define CS5535_DEV_ID 0x002E
|
||||
|
||||
//
|
||||
// Function 3 of 5530 PCI dev is Audio (ISA idx).
|
||||
//
|
||||
#define PCI_FUNC3_AUDIO 0x300
|
||||
#define PCI_AUDIO_CMD_REG 0x04
|
||||
|
||||
typedef unsigned char AUDIO_STATE;
|
||||
|
||||
#define AUDIO_STATE_IGNORE 0
|
||||
#define AUDIO_STATE_IN_RECORDING 0x01
|
||||
#define AUDIO_STATE_IN_OVERFLOW 0x02
|
||||
#define AUDIO_STATE_IN_STOPPED 0x03
|
||||
#define AUDIO_STATE_IN_MASK 0x0F
|
||||
#define AUDIO_STATE_OUT_PLAYING 0x10
|
||||
#define AUDIO_STATE_OUT_UNDERFLOW 0x20
|
||||
#define AUDIO_STATE_OUT_STOPPED 0x30
|
||||
#define AUDIO_STATE_OUT_MASK 0xF0
|
||||
|
||||
#define RECORD_RUNNING 0x01
|
||||
#define RECORD_OVERFLOW 0x02
|
||||
#define RECORD_STOPPED 0x03
|
||||
|
||||
#define PLAYBACK_RUNNING 0x10
|
||||
#define PLAYBACK_UNDERFLOW 0x20
|
||||
#define PLAYBACK_STOPPED 0x30
|
||||
|
||||
//
|
||||
// The CODEC commands are actually 16-bit words, into which is inserted
|
||||
// the codec "target" register, identified by a byte. The 5530 Codec
|
||||
// controller writes a command unsigned short of 32-bits, that includes the codec
|
||||
// command unsigned short.
|
||||
//
|
||||
#define CODEC_COMMAND_MASK 0xFF00FFFF
|
||||
|
||||
//
|
||||
// The Interaction with the CODEC is a bit cumbersome
|
||||
// because of the serial interface.
|
||||
//
|
||||
#define CODEC_STATUS_REG 0x08 // In Audio mem-map.
|
||||
#define CODEC_CMD_REG 0x0c // In audio mem-map.
|
||||
#define CODEC_CMD_VALID 0x00010000
|
||||
#define CODEC_STATUS_VALID 0x00020000
|
||||
#define CODEC_STATUS_NEW 0x00010000
|
||||
#define BIT_CODEC_READY 0x00800000
|
||||
|
||||
//
|
||||
// Registers for the 5535
|
||||
//
|
||||
#define CODEC_STATUS_REG_5535 0x08
|
||||
#define CODEC_CONTROL_REG_5535 0x0c
|
||||
|
||||
//
|
||||
// 5535 Bits
|
||||
//
|
||||
#define BIT_5535_CODEC_COMMAND_NEW 0x00010000
|
||||
#define BIT_5535_CODEC_STATUS_NEW 0x00020000
|
||||
#define BIT_5535_ACLINK_SHUTDOWN 0x00040000
|
||||
#define BIT_5535_ACLINK_WARM_RESET 0x00020000
|
||||
#define BIT_5535_CODEC_READY_PRIM 0x00800000
|
||||
|
||||
//
|
||||
// Codec register indexes. Note these are all shifted left by 16 bits.
|
||||
//
|
||||
#define RESET 0x00
|
||||
#define MASTER_VOLUME 0x02
|
||||
#define LINE_LEV_OUT_VOL 0x04
|
||||
#define MASTER_VOLUME_MONO 0x06
|
||||
#define MASTER_TONE_RL 0x08
|
||||
#define PC_BEEP_VOLUME 0x0a
|
||||
#define PHONE_VOLUME 0x0c
|
||||
#define MIC_VOLUME 0x0e
|
||||
#define LINE_IN_VOLUME 0x10
|
||||
#define CD_VOLUME 0x12
|
||||
#define VIDEO_VOLUME 0x14
|
||||
#define TV_VOLUME 0x16
|
||||
#define PCM_OUT_VOL 0x18
|
||||
#define RECORD_SELECT 0x1a
|
||||
#define RECORD_GAIN 0x1c
|
||||
#define RECORD_MIC_GAIN 0x1e
|
||||
#define GENERAL_PURPOSE 0x20
|
||||
#define CONTROL_3D 0x22
|
||||
#define MODEM_RATE 0x24
|
||||
#define POWERDOWN_CTRL_STAT 0x26
|
||||
#define EXTENDED_AUDIO_ID 0x28
|
||||
#define EXT_AUDIO_CTRL_STAT 0x2A
|
||||
#define PCM_FRONT_DAC_RATE 0x2C
|
||||
#define PCM_LR_ADC_RATE 0x32
|
||||
#define VENDOR_ID1 0x7c
|
||||
#define VENDOR_ID2 0x7e
|
||||
|
||||
#define MUTE_MASK 0x8000
|
||||
#define HEADHONE_AVAIL 0x0010
|
||||
#define LINE_LEV_RESET_VOL 0x0000 // the reset without the mask
|
||||
|
||||
#ifdef AC97_2DOT1_6BIT_COMPLIANT
|
||||
# define MASTER_ATTEN_CTL_BITS 6
|
||||
#else
|
||||
# define MASTER_ATTEN_CTL_BITS 5
|
||||
#endif
|
||||
|
||||
#define MASTER_VOLUME_MAX ( ( 1 << MASTER_ATTEN_CTL_BITS ) - 1 )
|
||||
#define LINE_LEV_OUT_MAX ( ( 1 << MASTER_ATTEN_CTL_BITS ) - 1 )
|
||||
|
||||
//
|
||||
// AD1819A registers
|
||||
//
|
||||
#define AD1819A_SER_CONF 0x74
|
||||
#define AD1819A_SER_CONF_DRQEN 0x08
|
||||
#define AD1819A_MISC 0x76
|
||||
#define AD1819A_PCM_SR0 0x78
|
||||
#define AD1819A_PCM_SR1 0x7A
|
||||
#define AD1819A_VENDORID1 0x7C
|
||||
#define AD1819A_VENDORID2 0x7E
|
||||
|
||||
//
|
||||
// Power Management bits
|
||||
//
|
||||
#define GEODEAUDIO_PWR_PR0 0x0100 // PCM in ADC's & input Mux Powerdown
|
||||
#define GEODEAUDIO_PWR_PR1 0x0200 // PCM out DACs Powerdown
|
||||
#define GEODEAUDIO_PWR_PR2 0x0400 // Analog Mixer powerdown (Vref still on)
|
||||
#define GEODEAUDIO_PWR_PR3 0x0800 // Analog Mxer powerdown (Vref off)
|
||||
#define GEODEAUDIO_PWR_PR4 0x1000 // Digital interface (AC-link) powerdown (external clk off)
|
||||
#define GEODEAUDIO_PWR_PR5 0x2000 // Internal Clk disable
|
||||
#define GEODEAUDIO_PWR_PR6 0x4000 // HP amp powerdown
|
||||
#define GEODEAUDIO_PWR_PR7 0x8000 // External Amplifier Power Down
|
||||
|
||||
#define GEODEAUDIO_PWR_D0 0x0000
|
||||
#define GEODEAUDIO_PWR_D1 GEODEAUDIO_PWR_EXTOFF
|
||||
#define GEODEAUDIO_PWR_D2 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_D3 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_D4 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3|GEODEAUDIO_PWR_PR4|GEODEAUDIO_PWR_PR5|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_ANLOFF GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3 // Analog section OFF
|
||||
#define GEODEAUDIO_PWR_EXTOFF GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7 // HP amp and External Amplifier OFF
|
||||
#define GEODEAUDIO_PWR_D1_HAWK GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3|GEODEAUDIO_PWR_PR4
|
||||
#define GEODEAUDIO_PWR_DIGOFF GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1 // Digital section OFF
|
||||
|
||||
#define GEODEAUDIO_PWRUP_STEP1 0x0F00 // Clear EAPD,PR6 and AC-link to power up external and HP amp and Digital interface
|
||||
#define GEODEAUDIO_PWRUP_STEP2 0x0700 // Clear PR3 to power up Analog (Vref off)
|
||||
#define GEODEAUDIO_PWRUP_STEP3 0x0300 // Clear PR2 to power up Analog (Vref on)
|
||||
#define GEODEAUDIO_PWRUP_STEP4 0x0100 // Clear PR1 to power up DAC
|
||||
#define GEODEAUDIO_PWRUP_STEP5 0x0000 // Clear PR0 to power up ADC
|
||||
|
||||
#define GEODEAUDIO_CODEC_POWER_ADC 0x0001
|
||||
#define GEODEAUDIO_CODEC_POWER_DAC 0x0002
|
||||
#define GEODEAUDIO_CODEC_POWER_ANL 0x0004
|
||||
#define GEODEAUDIO_CODEC_POWER_REF 0x0008
|
||||
|
||||
//
|
||||
// Device Power States
|
||||
//
|
||||
typedef enum _GEODEAUDIO_POWER_STATE
|
||||
{
|
||||
GEODEAUDIO_D0 = 0, // Full On: full power, full functionality
|
||||
GEODEAUDIO_D1, // Low Power On: fully functional at low power/performance
|
||||
GEODEAUDIO_D2, // Standby: partially powered with automatic wake
|
||||
GEODEAUDIO_D3, // Sleep: partially powered with device initiated wake
|
||||
GEODEAUDIO_D4, // Off: unpowered
|
||||
} GEODEAUDIO_POWER_STATE, *PGEODEAUDIO_POWER_STATE;
|
||||
|
||||
// PRD table flags
|
||||
#define PRD_JMP_BIT 0x20000000
|
||||
#define PRD_EOP_BIT 0x40000000
|
||||
#define PRD_EOT_BIT 0x80000000
|
||||
|
||||
typedef struct tagPRDEntry
|
||||
{
|
||||
unsigned long ulPhysAddr;
|
||||
unsigned long SizeFlags;
|
||||
} PRD_ENTRY, *PPRD_ENTRY;
|
||||
|
||||
|
||||
//
|
||||
// Command register bits
|
||||
//
|
||||
#define PCI_READS 0x00
|
||||
#define PCI_WRITES 0x08
|
||||
|
||||
#define ENABLE_BUSMASTER 0x01
|
||||
#define PAUSE_BUSMASTER 0x03
|
||||
#define STOP_BUSMASTER 0x00
|
||||
|
||||
#define CHANNEL0_PLAYBACK 0
|
||||
#define CHANNEL1_RECORD 1
|
||||
#define MAX_CHANNELS 2
|
||||
|
||||
23
drivers/audio/a5536/geode.lk
Normal file
23
drivers/audio/a5536/geode.lk
Normal file
@@ -0,0 +1,23 @@
|
||||
IMP
|
||||
_KernelAlloc core.KernelAlloc,
|
||||
_KernelFree core.KernelFree,
|
||||
_CommitPages core.CommitPages,
|
||||
_MapIoMem core.MapIoMem,
|
||||
_GetPgAddr core.GetPgAddr,
|
||||
_CreateRingBuffer core.CreateRingBuffer,
|
||||
_PciApi core.PciApi,
|
||||
_PciRead8 core.PciRead8,
|
||||
_PciRead16 core.PciRead16,
|
||||
_PciRead32 core.PciRead32,
|
||||
_PciWrite8 core.PciWrite8,
|
||||
_PciWrite16 core.PciWrite16,
|
||||
_PciWrite32 core.PciWrite32,
|
||||
_RegService core.RegService,
|
||||
_AttachIntHandler core.AttachIntHandler,
|
||||
_SysMsgBoardStr core.SysMsgBoardStr,
|
||||
_Delay core.Delay
|
||||
|
||||
|
||||
FIL geode.obj,
|
||||
vsprintf.obj,
|
||||
icompute.obj
|
||||
30
drivers/audio/a5536/makefile
Normal file
30
drivers/audio/a5536/makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDRHD = -shared -T ld.x -s --file-alignment 32
|
||||
|
||||
INCLUDES = -I ../../include
|
||||
|
||||
HFILES:= ../../include/types.h \
|
||||
../../include/syscall.h \
|
||||
../../include/pci.h \
|
||||
geode.h
|
||||
|
||||
SRC_DEP:=
|
||||
GEODE_SRC:= amd_geode.h
|
||||
|
||||
NAME:= geode
|
||||
GEODE:= geode.dll
|
||||
|
||||
all: $(GEODE)
|
||||
|
||||
$(GEODE): geode.obj $(SRC_DEP) $(HFILES) Makefile
|
||||
wlink name $(GEODE) SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @$(NAME).lk
|
||||
kpack.exe geode.dll geode.drv
|
||||
|
||||
geode.obj : geode.c $(SRC_DEP) $(HFILES) Makefile
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -o geode.obj geode.c
|
||||
|
||||
|
||||
|
||||
182
drivers/audio/a5536/pci.h
Normal file
182
drivers/audio/a5536/pci.h
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
u16_t device;
|
||||
u16_t ChipSet;
|
||||
}PciChipset_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define VENDOR_ATI 0x1002
|
||||
|
||||
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
/*
|
||||
* Under PCI, each device has 256 bytes of configuration address space,
|
||||
* of which the first 64 bytes are standardized as follows:
|
||||
*/
|
||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||
#define PCI_COMMAND_IO 0x01 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEMORY 0x02 /* Enable response in Memory space */
|
||||
#define PCI_COMMAND_MASTER 0x04 /* Enable bus mastering */
|
||||
#define PCI_COMMAND_SPECIAL 0x08 /* Enable response to special cycles */
|
||||
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
|
||||
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
|
||||
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
|
||||
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
|
||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
||||
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
|
||||
|
||||
#define PCI_STATUS 0x06 /* 16 bits */
|
||||
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
|
||||
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
|
||||
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
|
||||
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
|
||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
||||
|
||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
|
||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
#define PCI_HEADER_TYPE_NORMAL 0
|
||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||
|
||||
#define PCI_BIST 0x0f /* 8 bits */
|
||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
||||
|
||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
||||
/* Capability lists */
|
||||
|
||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
|
||||
#define PCI_CAP_ID_HT 0x08 /* HyperTransport */
|
||||
#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */
|
||||
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
|
||||
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
|
||||
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
|
||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||
#define PCI_CAP_SIZEOF 4
|
||||
|
||||
|
||||
/* AGP registers */
|
||||
|
||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_AGP_STATUS 4 /* Status register */
|
||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
|
||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
|
||||
#define PCI_AGP_SIZEOF 12
|
||||
|
||||
|
||||
#define PCI_MAP_REG_START 0x10
|
||||
#define PCI_MAP_REG_END 0x28
|
||||
#define PCI_MAP_ROM_REG 0x30
|
||||
|
||||
#define PCI_MAP_MEMORY 0x00000000
|
||||
#define PCI_MAP_IO 0x00000001
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE 0x00000007
|
||||
#define PCI_MAP_IO_TYPE 0x00000003
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
|
||||
#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
|
||||
#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
|
||||
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
|
||||
#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ATTR_MASK 0x00000003
|
||||
|
||||
#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
|
||||
#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
|
||||
|
||||
#define PCI_MAP_IS64BITMEM(b) \
|
||||
(((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
|
||||
|
||||
#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
|
||||
#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1))
|
||||
#define PCIGETMEMORY64(b) \
|
||||
(PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32))
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
|
||||
#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
|
||||
|
||||
#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
|
||||
#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
|
||||
|
||||
#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
|
||||
|
||||
|
||||
#ifndef PCI_DOM_MASK
|
||||
# define PCI_DOM_MASK 0x0ffu
|
||||
#endif
|
||||
#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu)
|
||||
|
||||
#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \
|
||||
(((d) & 0x00001fu) << 11) | \
|
||||
(((f) & 0x000007u) << 8))
|
||||
|
||||
#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK))
|
||||
#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11)
|
||||
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
|
||||
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
|
||||
|
||||
|
||||
typedef unsigned int PCITAG;
|
||||
|
||||
extern inline PCITAG
|
||||
pciTag(int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
const PciChipset_t *PciDevMatch(u16_t dev,const PciChipset_t *list);
|
||||
u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min);
|
||||
|
||||
#define PCI_ANY_ID (~0)
|
||||
|
||||
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d))!=-1)
|
||||
289
drivers/audio/sisnbook/codec.inc
Normal file
289
drivers/audio/sisnbook/codec.inc
Normal file
@@ -0,0 +1,289 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
AD_LOSEL equ BIT5
|
||||
AD_HPSEL equ BIT10
|
||||
|
||||
align 4
|
||||
proc detect_codec
|
||||
locals
|
||||
codec_id dd ?
|
||||
endl
|
||||
|
||||
stdcall codec_read, dword 0x7C
|
||||
shl eax, 16
|
||||
|
||||
|
||||
mov [codec_id], eax
|
||||
|
||||
stdcall codec_read, dword 0x7E
|
||||
or eax, [codec_id]
|
||||
|
||||
|
||||
mov [codec.chip_id], eax
|
||||
|
||||
and eax, 0xFFFFFF00
|
||||
|
||||
mov edi, codecs
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
test ebx, ebx
|
||||
jz .unknown
|
||||
|
||||
cmp eax, ebx
|
||||
jne .next
|
||||
mov eax, [edi+4]
|
||||
mov [codec.ac_vendor_ids], eax
|
||||
mov esi, eax
|
||||
call SysMsgBoardStr
|
||||
stdcall detect_chip, [edi+8]
|
||||
|
||||
ret
|
||||
.next:
|
||||
add edi, 12
|
||||
jmp @B
|
||||
.unknown:
|
||||
mov [codec.ac_vendor_ids], ac_unknown
|
||||
mov [codec.chip_ids], chip_unknown
|
||||
|
||||
mov esi, chip_unknown
|
||||
call SysMsgBoardStr
|
||||
mov eax, [codec.chip_id]
|
||||
call dword2str
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc detect_chip stdcall, chip_tab:dword
|
||||
|
||||
mov eax, [codec.chip_id]
|
||||
and eax, 0xFF
|
||||
|
||||
mov edi, [chip_tab]
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
cmp ebx, 0xFF
|
||||
je .unknown
|
||||
|
||||
cmp eax,ebx
|
||||
jne .next
|
||||
mov eax, [edi+4]
|
||||
mov [codec.chip_ids], eax
|
||||
mov esi, eax
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
.next:
|
||||
add edi, 8
|
||||
jmp @b
|
||||
.unknown:
|
||||
mov [codec.chip_ids], chip_unknown
|
||||
mov esi, chip_unknown
|
||||
call SysMsgBoardStr
|
||||
mov eax, [codec.chip_id]
|
||||
call dword2str
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc setup_codec
|
||||
|
||||
xor eax, eax
|
||||
stdcall codec_write, dword CODEC_AUX_VOL
|
||||
|
||||
mov eax, 0x0B0B
|
||||
stdcall codec_write, dword CODEC_MASTER_VOL_REG
|
||||
|
||||
mov ax, 0x08
|
||||
stdcall codec_write, dword 0x0C
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword CODEC_PCM_OUT_REG
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x10
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x12
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x16
|
||||
|
||||
|
||||
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG
|
||||
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1)
|
||||
or eax, BIT0 ; set VRA (BIT0)
|
||||
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG
|
||||
|
||||
stdcall set_sample_rate, dword 48000
|
||||
|
||||
.init_error:
|
||||
xor eax, eax ; exit with error
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; param
|
||||
; eax= volume -10000 - 0 for both channels
|
||||
|
||||
align 4
|
||||
set_master_vol:
|
||||
cmp eax, 0
|
||||
jl @F
|
||||
xor eax, eax
|
||||
jmp .set
|
||||
@@:
|
||||
cmp eax, -9450
|
||||
jg .set
|
||||
mov eax, -9450 ;clamp into 6 bits
|
||||
.set:
|
||||
cdq
|
||||
mov ebx, -150
|
||||
idiv ebx
|
||||
mov ah, al
|
||||
stdcall codec_write, dword CODEC_MASTER_VOL_REG
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
proc get_master_vol stdcall, pvol:dword
|
||||
|
||||
stdcall codec_read, dword CODEC_MASTER_VOL_REG
|
||||
and eax, 0x3F
|
||||
imul eax, -150
|
||||
mov ebx, [pvol]
|
||||
mov [ebx], eax
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc set_sample_rate stdcall, rate:dword
|
||||
mov eax, [rate]
|
||||
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG
|
||||
ret
|
||||
endp
|
||||
|
||||
patch_AD:
|
||||
stdcall codec_read, 0x76
|
||||
or ax, BIT5+BIT10
|
||||
stdcall codec_write, 0x76
|
||||
ret
|
||||
|
||||
|
||||
|
||||
align 16
|
||||
ac_unknown db 'unknown manufacturer',13,10,0
|
||||
ac_Realtek db 'Realtek Semiconductor',13,10,0
|
||||
ac_Analog db 'Analog Devices',13,10,0
|
||||
ac_CMedia db 'C-Media Electronics',13,10,0
|
||||
ac_Cirrus db 'Cirrus Logic',13,10,0
|
||||
|
||||
chip_unknown db 'unknown codec id ', 0
|
||||
|
||||
CHIP_ANALOG equ 0x41445300
|
||||
CHIP_REALTEK equ 0x414C4700
|
||||
CHIP_CMEDIA equ 0x434D4900
|
||||
CHIP_CIRRUS equ 0x43525900
|
||||
|
||||
align 16
|
||||
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
|
||||
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
|
||||
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
|
||||
dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus
|
||||
dd 0
|
||||
|
||||
align 16
|
||||
chips_Analog dd 0x03, chip_AD1819
|
||||
dd 0x40, chip_AD1881
|
||||
dd 0x48, chip_AD1881A
|
||||
dd 0x60, chip_AD1884
|
||||
dd 0x61, chip_AD1886
|
||||
dd 0x62, chip_AD1887
|
||||
dd 0x63, chip_AD1886A
|
||||
dd 0x70, chip_AD1980
|
||||
dd 0x75, chip_AD1985
|
||||
dd 0xFF
|
||||
|
||||
chips_Realtek:
|
||||
dd 0x10, chip_ALC201a
|
||||
dd 0x20, chip_ALC650
|
||||
dd 0x21, chip_ALC650D
|
||||
dd 0x22, chip_ALC650E
|
||||
dd 0x23, chip_ALC650F
|
||||
dd 0x60, chip_ALC655
|
||||
dd 0x80, chip_ALC658
|
||||
dd 0x81, chip_ALC658D
|
||||
dd 0x90, chip_ALC850
|
||||
dd 0xFF
|
||||
|
||||
chips_CMedia dd 0x41, chip_CM9738
|
||||
dd 0x61, chip_CM9739
|
||||
dd 0x69, chip_CM9780
|
||||
dd 0x78, chip_CM9761
|
||||
dd 0x82, chip_CM9761
|
||||
dd 0x83, chip_CM9761
|
||||
dd 0xFF
|
||||
|
||||
chips_Cirrus dd 0x00, chip_CS4297
|
||||
dd 0x10, chip_CS4297A
|
||||
dd 0x20, chip_CS4298
|
||||
dd 0x28, chip_CS4294
|
||||
dd 0x30, chip_CS4299
|
||||
dd 0x34, chip_CS4299D
|
||||
dd 0x48, chip_CS4201
|
||||
dd 0x58, chip_CS4205
|
||||
dd 0x60, chip_CS4291
|
||||
dd 0x70, chip_CS4202
|
||||
dd 0xFF
|
||||
|
||||
|
||||
align 16
|
||||
;Analog Devices
|
||||
chip_AD1819 db 'AD1819 ',0dh,0ah,00h
|
||||
chip_AD1881 db 'AD1881 ',0dh,0ah,00h
|
||||
chip_AD1881A db 'AD1881A',0dh,0ah,00h
|
||||
chip_AD1884 db 'AD1885 ',0dh,0ah,00h
|
||||
chip_AD1885 db 'AD1885 ',0dh,0ah,00h
|
||||
chip_AD1886 db 'AD1886 ',0dh,0ah,00h
|
||||
chip_AD1886A db 'AD1886A',0dh,0ah,00h
|
||||
chip_AD1887 db 'AD1887 ',0dh,0ah,00h
|
||||
chip_AD1980 db 'AD1980 ',0dh,0ah,00h
|
||||
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
|
||||
|
||||
;Realtek
|
||||
chip_ALC201a db 'ALC201a',0dh,0ah,00h
|
||||
chip_ALC650 db 'ALC650 ',0dh,0ah,00h
|
||||
chip_ALC650D db 'ALC650D',0dh,0ah,00h
|
||||
chip_ALC650E db 'ALC650E',0dh,0ah,00h
|
||||
chip_ALC650F db 'ALC650F',0dh,0ah,00h
|
||||
chip_ALC655 db 'ALC655 ',0dh,0ah,00h
|
||||
chip_ALC658 db 'ALC658 ',0dh,0ah,00h
|
||||
chip_ALC658D db 'ALC658D',0dh,0ah,00h
|
||||
chip_ALC850 db 'ALC850 ',0dh,0ah,00h
|
||||
|
||||
;CMedia
|
||||
chip_CM9738 db 'CMI9738', 0dh,0ah,0
|
||||
chip_CM9739 db 'CMI9739', 0dh,0ah,0
|
||||
chip_CM9780 db 'CMI9780', 0dh,0ah,0
|
||||
chip_CM9761 db 'CMI9761', 0dh,0ah,0
|
||||
|
||||
;Cirrus
|
||||
chip_CS4297 db 'CS4297',13,10,0
|
||||
chip_CS4297A db 'CS4297A',13,10,0
|
||||
chip_CS4298 db 'CS4298',13,10,0
|
||||
chip_CS4294 db 'CS4294',13,10,0
|
||||
chip_CS4299 db 'CS4299',13,10,0
|
||||
chip_CS4299D db 'CS4299D',13,10,0
|
||||
chip_CS4201 db 'CS4201',13,10,0
|
||||
chip_CS4205 db 'CS4205',13,10,0
|
||||
chip_CS4291 db 'CS4291',13,10,0
|
||||
chip_CS4202 db 'CS4202',13,10,0
|
||||
|
||||
|
||||
14
drivers/audio/sisnbook/readme.txt
Normal file
14
drivers/audio/sisnbook/readme.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Немного переделал драйвер звука для чипа SIS
|
||||
|
||||
-добавил подключение PCI устройства к контроллеру прерывания
|
||||
(БИОС неназначил номер прерывания) назначается IRQ 5
|
||||
-изменил чтение регистра кодека (считывание и запись производится через 'семафор')
|
||||
|
||||
в остальном оставил все как есть :)
|
||||
|
||||
SIS.obj - просто бинарник
|
||||
sis.asm - исходник
|
||||
codec.inc - (добавил номер определения своего кодека)
|
||||
|
||||
|
||||
G@K
|
||||
1365
drivers/audio/sisnbook/sis.asm
Normal file
1365
drivers/audio/sisnbook/sis.asm
Normal file
File diff suppressed because it is too large
Load Diff
151
drivers/imports.inc
Normal file
151
drivers/imports.inc
Normal file
@@ -0,0 +1,151 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; all exported kernel functions and data
|
||||
|
||||
if used RegService
|
||||
extrn RegService
|
||||
end if
|
||||
if used GetService
|
||||
extrn GetService
|
||||
end if
|
||||
if used ServiceHandler
|
||||
extrn ServiceHandler
|
||||
end if
|
||||
if used AttachIntHandler
|
||||
extrn AttachIntHandler
|
||||
end if
|
||||
if used FpuSave
|
||||
extrn FpuSave
|
||||
end if
|
||||
if used FpuRestore
|
||||
extrn FpuRestore
|
||||
end if
|
||||
|
||||
if used PciApi
|
||||
extrn PciApi
|
||||
end if
|
||||
if used PciRead32
|
||||
extrn PciRead32
|
||||
end if
|
||||
if used PciRead8
|
||||
extrn PciRead8
|
||||
end if
|
||||
if used PciWrite8
|
||||
extrn PciWrite8
|
||||
end if
|
||||
|
||||
if used AllocPage
|
||||
extrn AllocPage
|
||||
end if
|
||||
if used AllocPages
|
||||
extrn AllocPages
|
||||
end if
|
||||
if used FreePage
|
||||
extrn FreePage
|
||||
end if
|
||||
if used MapPage
|
||||
extrn MapPage
|
||||
end if
|
||||
if used MapSpace
|
||||
extrn MapSpace
|
||||
end if
|
||||
if used GetPgAddr
|
||||
extrn GetPgAddr
|
||||
end if
|
||||
if used CommitPages
|
||||
extrn CommitPages
|
||||
end if
|
||||
if used ReleasePages
|
||||
extrn ReleasePages
|
||||
end if
|
||||
|
||||
if used AllocKernelSpace
|
||||
extrn AllocKernelSpace
|
||||
end if
|
||||
if used FreeKernelSpace
|
||||
extrn FreeKernelSpace
|
||||
end if
|
||||
if used KernelAlloc
|
||||
extrn KernelAlloc
|
||||
end if
|
||||
if used KernelFree
|
||||
extrn KernelFree
|
||||
end if
|
||||
if used UserAlloc
|
||||
extrn UserAlloc
|
||||
end if
|
||||
if used UserFree
|
||||
extrn UserFree
|
||||
end if
|
||||
if used Kmalloc
|
||||
extrn Kmalloc
|
||||
end if
|
||||
if used Kfree
|
||||
extrn Kfree
|
||||
end if
|
||||
|
||||
if used CreateObject
|
||||
extrn CreateObject
|
||||
end if
|
||||
if used DestroyObject
|
||||
extrn DestroyObject
|
||||
end if
|
||||
if used CreateEvent
|
||||
extrn CreateEvent
|
||||
end if
|
||||
if used RaiseEvent
|
||||
extrn RaiseEvent
|
||||
end if
|
||||
if used WaitEvent
|
||||
extrn WaitEvent
|
||||
end if
|
||||
if used DestroyEvent
|
||||
extrn DestroyEvent
|
||||
end if
|
||||
if used ClearEvent
|
||||
extrn ClearEvent
|
||||
end if
|
||||
|
||||
if used LoadCursor
|
||||
extrn LoadCursor
|
||||
end if
|
||||
if used SetHwCursor
|
||||
extrn SetHwCursor
|
||||
end if
|
||||
if used HwCursorRestore
|
||||
extrn HwCursorRestore
|
||||
end if
|
||||
if used HwCursorCreate
|
||||
extrn HwCursorCreate
|
||||
end if
|
||||
|
||||
if used SysMsgBoardStr
|
||||
extrn SysMsgBoardStr
|
||||
end if
|
||||
if used GetCurrentTask
|
||||
extrn GetCurrentTask
|
||||
end if
|
||||
if used LoadFile
|
||||
extrn LoadFile
|
||||
end if
|
||||
if used SendEvent
|
||||
extrn SendEvent
|
||||
end if
|
||||
if used SetMouseData
|
||||
extrn SetMouseData
|
||||
end if
|
||||
if used Sleep
|
||||
extrn Sleep
|
||||
end if
|
||||
if used GetTimerTicks
|
||||
extrn GetTimerTicks
|
||||
end if
|
||||
if used LFBAddress
|
||||
extrn LFBAddress
|
||||
end if
|
||||
|
||||
60
drivers/include/link.h
Normal file
60
drivers/include/link.h
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
typedef struct link
|
||||
{
|
||||
struct link *prev;
|
||||
struct link *next;
|
||||
}link_t;
|
||||
|
||||
#define LIST_INITIALIZE(name) \
|
||||
link_t name = { .prev = &name, .next = &name }
|
||||
|
||||
#define list_get_instance(link, type, member) \
|
||||
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
|
||||
|
||||
static inline void link_initialize(link_t *link)
|
||||
{
|
||||
link->prev = NULL;
|
||||
link->next = NULL;
|
||||
}
|
||||
|
||||
static inline void list_initialize(link_t *head)
|
||||
{
|
||||
head->prev = head;
|
||||
head->next = head;
|
||||
}
|
||||
|
||||
static inline void list_append(link_t *link, link_t *head)
|
||||
{
|
||||
link->prev = head->prev;
|
||||
link->next = head;
|
||||
head->prev->next = link;
|
||||
head->prev = link;
|
||||
}
|
||||
|
||||
static inline void list_remove(link_t *link)
|
||||
{
|
||||
link->next->prev = link->prev;
|
||||
link->prev->next = link->next;
|
||||
link_initialize(link);
|
||||
}
|
||||
|
||||
static inline Bool list_empty(link_t *head)
|
||||
{
|
||||
return head->next == head ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static inline void list_prepend(link_t *link, link_t *head)
|
||||
{
|
||||
link->next = head->next;
|
||||
link->prev = head;
|
||||
head->next->prev = link;
|
||||
head->next = link;
|
||||
}
|
||||
|
||||
static inline list_insert(link_t *new, link_t *old)
|
||||
{
|
||||
new->prev = old->prev;
|
||||
new->next = old;
|
||||
new->prev->next = new;
|
||||
old->prev = new;
|
||||
}
|
||||
183
drivers/include/pci.h
Normal file
183
drivers/include/pci.h
Normal file
@@ -0,0 +1,183 @@
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
u16_t device;
|
||||
u16_t ChipSet;
|
||||
}PciChipset_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define VENDOR_ATI 0x1002
|
||||
|
||||
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
/*
|
||||
* Under PCI, each device has 256 bytes of configuration address space,
|
||||
* of which the first 64 bytes are standardized as follows:
|
||||
*/
|
||||
#define PCI_VENDOR_ID 0x000 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x002 /* 16 bits */
|
||||
#define PCI_COMMAND 0x004 /* 16 bits */
|
||||
#define PCI_COMMAND_IO 0x001 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEMORY 0x002 /* Enable response in Memory space */
|
||||
#define PCI_COMMAND_MASTER 0x004 /* Enable bus mastering */
|
||||
#define PCI_COMMAND_SPECIAL 0x008 /* Enable response to special cycles */
|
||||
#define PCI_COMMAND_INVALIDATE 0x010 /* Use memory write and invalidate */
|
||||
#define PCI_COMMAND_VGA_PALETTE 0x020 /* Enable palette snooping */
|
||||
#define PCI_COMMAND_PARITY 0x040 /* Enable parity checking */
|
||||
#define PCI_COMMAND_WAIT 0x080 /* Enable address/data stepping */
|
||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
||||
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
|
||||
|
||||
#define PCI_STATUS 0x006 /* 16 bits */
|
||||
#define PCI_STATUS_CAP_LIST 0x010 /* Support Capability List */
|
||||
#define PCI_STATUS_66MHZ 0x020 /* Support 66 Mhz PCI 2.1 bus */
|
||||
#define PCI_STATUS_UDF 0x040 /* Support User Definable Features [obsolete] */
|
||||
#define PCI_STATUS_FAST_BACK 0x080 /* Accept fast-back to back */
|
||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
||||
|
||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
|
||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
#define PCI_HEADER_TYPE_NORMAL 0
|
||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||
|
||||
#define PCI_BIST 0x0f /* 8 bits */
|
||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
||||
|
||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
||||
/* Capability lists */
|
||||
|
||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
|
||||
#define PCI_CAP_ID_HT 0x08 /* HyperTransport */
|
||||
#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */
|
||||
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
|
||||
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
|
||||
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
|
||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||
#define PCI_CAP_SIZEOF 4
|
||||
|
||||
|
||||
/* AGP registers */
|
||||
|
||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_AGP_STATUS 4 /* Status register */
|
||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
|
||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
|
||||
#define PCI_AGP_SIZEOF 12
|
||||
|
||||
|
||||
#define PCI_MAP_REG_START 0x10
|
||||
#define PCI_MAP_REG_END 0x28
|
||||
#define PCI_MAP_ROM_REG 0x30
|
||||
|
||||
#define PCI_MAP_MEMORY 0x00000000
|
||||
#define PCI_MAP_IO 0x00000001
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE 0x00000007
|
||||
#define PCI_MAP_IO_TYPE 0x00000003
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
|
||||
#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
|
||||
#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
|
||||
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
|
||||
#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ATTR_MASK 0x00000003
|
||||
|
||||
|
||||
|
||||
#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
|
||||
#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
|
||||
|
||||
#define PCI_MAP_IS64BITMEM(b) \
|
||||
(((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
|
||||
|
||||
#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
|
||||
#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1))
|
||||
#define PCIGETMEMORY64(b) \
|
||||
(PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32))
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
|
||||
#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
|
||||
|
||||
#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
|
||||
#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
|
||||
|
||||
#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
|
||||
|
||||
|
||||
#ifndef PCI_DOM_MASK
|
||||
# define PCI_DOM_MASK 0x0ffu
|
||||
#endif
|
||||
#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu)
|
||||
|
||||
#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \
|
||||
(((d) & 0x00001fu) << 11) | \
|
||||
(((f) & 0x000007u) << 8))
|
||||
|
||||
#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK))
|
||||
#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11)
|
||||
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
|
||||
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
|
||||
|
||||
|
||||
#define PCI_CMD_STAT_REG 0x04
|
||||
|
||||
|
||||
typedef unsigned int PCITAG;
|
||||
|
||||
extern inline PCITAG
|
||||
pciTag(int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
const PciChipset_t *PciDevMatch(u16_t dev,const PciChipset_t *list);
|
||||
u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min);
|
||||
316
drivers/include/syscall.h
Normal file
316
drivers/include/syscall.h
Normal file
@@ -0,0 +1,316 @@
|
||||
|
||||
#define OS_BASE 0x80000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t handle;
|
||||
u32_t io_code;
|
||||
void *input;
|
||||
int inp_size;
|
||||
void *output;
|
||||
int out_size;
|
||||
}ioctl_t;
|
||||
|
||||
typedef int (__stdcall *srv_proc_t)(ioctl_t *);
|
||||
|
||||
#define ERR_OK 0
|
||||
#define ERR_PARAM -1
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int)__asm__("_drvEntry");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STDCALL __attribute__ ((stdcall)) __attribute__ ((dllimport))
|
||||
#define IMPORT __attribute__ ((dllimport))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SysMsgBoardStr __SysMsgBoardStr
|
||||
#define PciApi __PciApi
|
||||
//#define RegService __RegService
|
||||
#define CreateObject __CreateObject
|
||||
#define DestroyObject __DestroyObject
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PG_SW 0x003
|
||||
#define PG_NOCACHE 0x018
|
||||
|
||||
void* STDCALL AllocKernelSpace(size_t size)__asm__("AllocKernelSpace");
|
||||
void* STDCALL KernelAlloc(size_t size)__asm__("KernelAlloc");
|
||||
void* STDCALL KernelFree(void *mem)__asm__("KernelFree");
|
||||
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc");
|
||||
int STDCALL UserFree(void *mem)__asm__("UserFree");
|
||||
|
||||
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages");
|
||||
|
||||
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer");
|
||||
|
||||
u32_t STDCALL RegService(char *name, srv_proc_t proc)__asm__("RegService");
|
||||
|
||||
int STDCALL AttachIntHandler(int irq, void *handler, u32_t access) __asm__("AttachIntHandler");
|
||||
|
||||
|
||||
//void *CreateObject(u32 pid, size_t size);
|
||||
//void *DestroyObject(void *obj);
|
||||
|
||||
addr_t STDCALL MapIoMem(addr_t base, size_t size, u32_t flags)__asm__("MapIoMem");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void STDCALL SetMouseData(int btn, int x, int y,
|
||||
int z, int h)__asm__("SetMouseData");
|
||||
|
||||
static u32_t PciApi(int cmd);
|
||||
|
||||
u8_t STDCALL PciRead8 (u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead8");
|
||||
u16_t STDCALL PciRead16(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead16");
|
||||
u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
|
||||
|
||||
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8");
|
||||
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");
|
||||
u32_t STDCALL PciWrite32(u32_t bus, u32_t devfn, u32_t reg,u32_t val)__asm__("PciWrite32");
|
||||
|
||||
#define pciReadByte(tag, reg) \
|
||||
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadWord(tag, reg) \
|
||||
PciRead16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadLong(tag, reg) \
|
||||
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciWriteByte(tag, reg, val) \
|
||||
PciWrite8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteWord(tag, reg, val) \
|
||||
PciWrite16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteLong(tag, reg, val) \
|
||||
PciWrite32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int dbg_open(char *path);
|
||||
int dbgprintf(const char* format, ...);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern inline int GetScreenSize()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(1));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenBpp()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(2));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenPitch()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(3));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline u32_t GetPgAddr(void *mem)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__GetPgAddr \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (mem) );
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CommitPages"
|
||||
::"a" (page), "b"(mem),"c"(size>>12)
|
||||
:"edx" );
|
||||
__asm__ __volatile__ ("":::"eax","ebx","ecx");
|
||||
};
|
||||
|
||||
extern inline void UnmapPages(void *mem, size_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__UnmapPages"
|
||||
::"a" (mem), "c"(size>>12)
|
||||
:"edx");
|
||||
__asm__ __volatile__ ("":::"eax","ecx");
|
||||
};
|
||||
|
||||
extern inline void usleep(u32_t delay)
|
||||
{
|
||||
if( !delay )
|
||||
delay++;
|
||||
delay*=1000;
|
||||
|
||||
while(delay--)
|
||||
__asm__ __volatile__ (
|
||||
"xorl %%eax, %%eax \n\t"
|
||||
"cpuid \n\t"
|
||||
:::"eax","ebx","ecx","edx");
|
||||
};
|
||||
|
||||
extern inline u32_t __PciApi(int cmd)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__PciApi"
|
||||
:"=a" (retval)
|
||||
:"a" (cmd)
|
||||
:"memory");
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void* __CreateObject(u32_t pid, size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CreateObject \n\t"
|
||||
:"=a" (retval)
|
||||
:"a" (size),"b"(pid)
|
||||
:"esi","edi", "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline void *__DestroyObject(void *obj)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__DestroyObject"
|
||||
:
|
||||
:"a" (obj)
|
||||
:"ebx","edx","esi","edi", "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
u32 __RegService(char *name, srv_proc_t proc)
|
||||
{
|
||||
u32 retval;
|
||||
|
||||
asm __volatile__
|
||||
(
|
||||
"pushl %%eax \n\t"
|
||||
"pushl %%ebx \n\t"
|
||||
"call *__imp__RegService \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (proc), "b" (name)
|
||||
:"memory"
|
||||
);
|
||||
return retval;
|
||||
};
|
||||
*/
|
||||
|
||||
extern inline u32_t safe_cli(void)
|
||||
{
|
||||
u32_t ifl;
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"popl %0\n\t"
|
||||
"cli\n"
|
||||
: "=r" (ifl));
|
||||
return ifl;
|
||||
}
|
||||
|
||||
extern inline void safe_sti(u32_t ifl)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"pushl %0\n\t"
|
||||
"popf\n"
|
||||
: : "r" (ifl)
|
||||
);
|
||||
}
|
||||
|
||||
extern inline void __clear (void * dst, unsigned len)
|
||||
{
|
||||
u32_t tmp;
|
||||
__asm__ __volatile__ (
|
||||
// "xorl %%eax, %%eax \n\t"
|
||||
"cld \n\t"
|
||||
"rep stosb \n"
|
||||
:"=c"(tmp),"=D"(tmp)
|
||||
:"a"(0),"c"(len),"D"(dst));
|
||||
__asm__ __volatile__ ("":::"ecx","edi");
|
||||
};
|
||||
|
||||
extern inline void out8(const u16_t port, const u8_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outb %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline void out16(const u16_t port, const u16_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outw %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline void out32(const u16_t port, const u32_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outl %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline u8_t in8(const u16_t port)
|
||||
{
|
||||
u8_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inb %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline u16_t in16(const u16_t port)
|
||||
{
|
||||
u16_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inw %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline u32_t in32(const u16_t port)
|
||||
{
|
||||
u32_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inl %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline void delay(int time)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__Delay"
|
||||
::"b" (time));
|
||||
__asm__ __volatile__ (
|
||||
"":::"ebx");
|
||||
|
||||
}
|
||||
|
||||
extern inline void change_task()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__ChangeTask");
|
||||
}
|
||||
|
||||
24
drivers/include/types.h
Normal file
24
drivers/include/types.h
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#define NULL (void*)0
|
||||
|
||||
|
||||
typedef unsigned char u8_t;
|
||||
typedef unsigned short int u16_t;
|
||||
typedef unsigned int u32_t;
|
||||
typedef unsigned long long u64_t;
|
||||
|
||||
typedef signed char i8_t;
|
||||
typedef signed short int i16_t;
|
||||
|
||||
typedef unsigned int addr_t;
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef unsigned int count_t;
|
||||
typedef unsigned int eflags_t;
|
||||
|
||||
typedef unsigned int Bool;
|
||||
|
||||
#define TRUE (Bool)1
|
||||
#define FALSE (Bool)0
|
||||
|
||||
|
||||
141
drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc
Normal file
141
drivers/mouse/ps2mouse4d/trunk/ps2m_iofuncs.inc
Normal file
@@ -0,0 +1,141 @@
|
||||
kbd_read:
|
||||
push ecx edx
|
||||
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
kr_loop:
|
||||
in al,0x64
|
||||
test al,1
|
||||
jnz kr_ready
|
||||
loop kr_loop
|
||||
mov ah,1
|
||||
jmp kr_exit
|
||||
kr_ready:
|
||||
push ecx
|
||||
mov ecx,32
|
||||
kr_delay:
|
||||
loop kr_delay
|
||||
pop ecx
|
||||
in al,0x60
|
||||
xor ah,ah
|
||||
kr_exit:
|
||||
pop edx ecx
|
||||
ret
|
||||
|
||||
|
||||
kbd_write:
|
||||
|
||||
push ecx edx
|
||||
|
||||
mov dl,al
|
||||
in al,0x60
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
kw_loop:
|
||||
in al,0x64
|
||||
test al,2
|
||||
jz kw_ok
|
||||
loop kw_loop
|
||||
mov ah,1
|
||||
jmp kw_exit
|
||||
kw_ok:
|
||||
mov al,dl
|
||||
out 0x60,al
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
kw_loop3:
|
||||
in al,0x64
|
||||
test al,2
|
||||
jz kw_ok3
|
||||
loop kw_loop3
|
||||
mov ah,1
|
||||
jmp kw_exit
|
||||
kw_ok3:
|
||||
mov ah,8
|
||||
kw_loop4:
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
kw_loop5:
|
||||
in al,0x64
|
||||
test al,1
|
||||
jnz kw_ok4
|
||||
loop kw_loop5
|
||||
dec ah
|
||||
jnz kw_loop4
|
||||
kw_ok4:
|
||||
xor ah,ah
|
||||
kw_exit:
|
||||
pop edx ecx
|
||||
ret
|
||||
|
||||
|
||||
kbd_cmd:
|
||||
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
c_wait:
|
||||
in al,0x64
|
||||
test al,2
|
||||
jz c_send
|
||||
loop c_wait
|
||||
jmp c_error
|
||||
c_send:
|
||||
mov al,bl
|
||||
out 0x64,al
|
||||
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
|
||||
c_accept:
|
||||
in al,0x64
|
||||
test al,2
|
||||
jz c_ok
|
||||
loop c_accept
|
||||
c_error:
|
||||
mov ah,1
|
||||
jmp c_exit
|
||||
c_ok:
|
||||
xor ah,ah
|
||||
c_exit:
|
||||
ret
|
||||
|
||||
mouse_cmd:
|
||||
mov [mouse_cmd_byte], al
|
||||
mov [mouse_nr_resends], 5
|
||||
.resend:
|
||||
mov bl, 0xd4
|
||||
call kbd_cmd
|
||||
cmp ah,1
|
||||
je .fail
|
||||
|
||||
mov al, [mouse_cmd_byte]
|
||||
call kbd_write
|
||||
cmp ah, 1
|
||||
je .fail
|
||||
|
||||
call mouse_read
|
||||
|
||||
cmp al, 0xFA
|
||||
jne .noack
|
||||
clc
|
||||
ret
|
||||
.noack:
|
||||
cmp al, 0xFE ; resend
|
||||
jne .noresend
|
||||
dec [mouse_nr_resends]
|
||||
jnz .resend
|
||||
.noresend:
|
||||
.fail:
|
||||
stc
|
||||
ret
|
||||
|
||||
|
||||
mouse_read:
|
||||
mov [mouse_nr_tries], 100
|
||||
.repeat:
|
||||
call kbd_read
|
||||
cmp ah, 1
|
||||
jne .fin
|
||||
mov esi, 10
|
||||
call Sleep
|
||||
dec [mouse_nr_tries]
|
||||
jnz .repeat
|
||||
|
||||
stc
|
||||
ret
|
||||
|
||||
.fin:
|
||||
clc
|
||||
ret
|
||||
135
drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc
Normal file
135
drivers/mouse/ps2mouse4d/trunk/ps2m_irqh.inc
Normal file
@@ -0,0 +1,135 @@
|
||||
;**************************************
|
||||
;* IRQ HANDLER FOR PS/2 MOUSE *
|
||||
;**************************************
|
||||
|
||||
proc irq_handler
|
||||
|
||||
; call Wait8042BufferEmpty ;clear buffer
|
||||
in al,0x60 ;get scan-code
|
||||
|
||||
cmp [mouse_byte],0
|
||||
je .byte1
|
||||
cmp [mouse_byte],1
|
||||
je .byte2
|
||||
cmp [mouse_byte],2
|
||||
je .byte3
|
||||
cmp [mouse_byte],3
|
||||
je .byte4
|
||||
jmp .error
|
||||
|
||||
.byte1:
|
||||
test al,1000b ;first byte?
|
||||
jz .error
|
||||
mov [first_byte],al
|
||||
inc [mouse_byte]
|
||||
jmp .exit
|
||||
|
||||
.byte2:
|
||||
mov [second_byte],al
|
||||
inc [mouse_byte]
|
||||
jmp .exit
|
||||
|
||||
.byte3:
|
||||
mov [third_byte],al
|
||||
cmp [MouseType],MT_3B
|
||||
je .full_packet
|
||||
inc [mouse_byte]
|
||||
jmp .exit
|
||||
|
||||
.byte4:
|
||||
mov [fourth_byte],al
|
||||
|
||||
|
||||
.full_packet:
|
||||
mov [mouse_byte],0
|
||||
mov al,byte [first_byte]
|
||||
and eax,7
|
||||
mov byte [ButtonState],al
|
||||
|
||||
cmp [MouseType],MT_3B
|
||||
je .xy_moving
|
||||
mov al,[fourth_byte]
|
||||
cmp [MouseType],MT_3BScroll
|
||||
je .z_moving
|
||||
|
||||
mov ah,al
|
||||
and ah,00110000b
|
||||
shr ah,1
|
||||
or byte [ButtonState],ah
|
||||
and al,00001111b
|
||||
bt eax,3
|
||||
jnc .z_moving
|
||||
or al,11110000b
|
||||
|
||||
.z_moving:
|
||||
movsx eax,al
|
||||
mov [ZMoving],eax
|
||||
|
||||
.xy_moving:
|
||||
mov ah,0
|
||||
mov al,[first_byte]
|
||||
test al,10000b
|
||||
jz @f
|
||||
mov ah,0FFh
|
||||
|
||||
@@:
|
||||
mov al,[second_byte]
|
||||
cwde
|
||||
mov [XMoving],eax
|
||||
|
||||
mov ah,0
|
||||
mov al,[first_byte]
|
||||
test al,100000b
|
||||
jz @f
|
||||
mov ah,0FFh
|
||||
|
||||
@@:
|
||||
mov al,[third_byte]
|
||||
cwde
|
||||
|
||||
@@:
|
||||
mov [YMoving],eax
|
||||
|
||||
mov eax,[ZMoving]
|
||||
test eax,1
|
||||
jnz .vert
|
||||
|
||||
sar eax,1
|
||||
push eax
|
||||
push 0
|
||||
jmp @f
|
||||
|
||||
.vert:
|
||||
push 0
|
||||
push eax
|
||||
|
||||
@@:
|
||||
|
||||
stdcall SetMouseData, [ButtonState], [XMoving], [YMoving]
|
||||
|
||||
jmp .exit
|
||||
|
||||
.error:
|
||||
mov [mouse_byte],0
|
||||
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
;***********************************************
|
||||
;* Waiting for clearing I8042 buffer *
|
||||
;* Retutned state: *
|
||||
;* ZF is set - good ending, *
|
||||
;* ZF is cleared - time-out error. *
|
||||
;***********************************************
|
||||
;Wait8042BufferEmpty:
|
||||
; push ecx
|
||||
; xor ecx,ecx
|
||||
; @@:
|
||||
; in al,64h
|
||||
; test al,00000010b
|
||||
; loopnz @b
|
||||
; pop ecx
|
||||
;
|
||||
; ret
|
||||
268
drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm
Normal file
268
drivers/mouse/ps2mouse4d/trunk/ps2mouse.asm
Normal file
@@ -0,0 +1,268 @@
|
||||
format MS COFF
|
||||
|
||||
include '../../../proc32.inc'
|
||||
include '../../../imports.inc'
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
public START
|
||||
public version
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
|
||||
MT_3B equ 0
|
||||
MT_3BScroll equ 3
|
||||
MT_5BScroll equ 4
|
||||
|
||||
PS2_DRV_VER equ 1
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], DRV_ENTRY
|
||||
jne .fin
|
||||
.init:
|
||||
|
||||
call detect_mouse
|
||||
test eax,eax
|
||||
jnz .exit
|
||||
|
||||
mov [MouseType],MT_3B
|
||||
|
||||
call try_mode_ID3
|
||||
test eax,eax
|
||||
jnz .stop_try
|
||||
mov [MouseType],MT_3BScroll
|
||||
|
||||
call try_mode_ID4
|
||||
test eax,eax
|
||||
jnz .stop_try
|
||||
mov [MouseType],MT_5BScroll
|
||||
|
||||
.stop_try:
|
||||
|
||||
mov bl, 0x20 ; read command byte
|
||||
call kbd_cmd
|
||||
cmp ah,1
|
||||
je .exit
|
||||
|
||||
call kbd_read
|
||||
cmp ah,1
|
||||
je .exit
|
||||
|
||||
or al, 10b
|
||||
push eax
|
||||
mov bl, 0x60 ; write command byte
|
||||
call kbd_cmd
|
||||
cmp ah,1
|
||||
je .exit
|
||||
|
||||
pop eax
|
||||
call kbd_write
|
||||
cmp ah,1
|
||||
je .exit
|
||||
|
||||
mov al, 0xF4 ; enable data reporting
|
||||
call mouse_cmd
|
||||
|
||||
mov bl, 0xAE ; enable keyboard interface
|
||||
call kbd_cmd
|
||||
|
||||
stdcall AttachIntHandler, 12, irq_handler, dword 0
|
||||
stdcall RegService, my_service, service_proc
|
||||
ret
|
||||
|
||||
.fin:
|
||||
;stdcall DetachIntHandler, 12, irq_handler
|
||||
mov bl, 0xA7 ; disable mouse interface
|
||||
call kbd_cmd
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.exit:
|
||||
mov bl, 0xA7 ; disable mouse interface
|
||||
call kbd_cmd
|
||||
mov bl, 0xAE ; enable keyboard interface
|
||||
call kbd_cmd
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
mov edi, [ioctl]
|
||||
mov eax, [edi+IOCTL.io_code]
|
||||
test eax, eax
|
||||
jz .getversion
|
||||
cmp eax,1
|
||||
jz .gettype
|
||||
|
||||
.err:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
.ok:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.getversion:
|
||||
cmp [edi+IOCTL.out_size], 4
|
||||
jb .err
|
||||
mov edi, [edi+IOCTL.output]
|
||||
mov dword [edi], PS2_DRV_VER ; version of driver
|
||||
jmp .ok
|
||||
.gettype:
|
||||
cmp [edi+IOCTL.out_size], 4
|
||||
jb .err
|
||||
mov edi, [edi+IOCTL.output]
|
||||
mov eax,[MouseType]
|
||||
mov dword [edi], eax ; mouse type
|
||||
jmp .ok
|
||||
endp
|
||||
|
||||
detect_mouse:
|
||||
|
||||
mov bl, 0xAD ; disable keyboard interface
|
||||
call kbd_cmd
|
||||
cmp ah,1
|
||||
je .fail
|
||||
|
||||
mov bl, 0xA8 ; enable mouse interface
|
||||
call kbd_cmd
|
||||
cmp ah,1
|
||||
je .fail
|
||||
|
||||
mov al, 0xFF ; reset
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
|
||||
call mouse_read
|
||||
jc .fail
|
||||
cmp al, 0xAA
|
||||
jne .fail ; dead mouse
|
||||
|
||||
; get device ID
|
||||
call mouse_read
|
||||
jc .fail
|
||||
cmp al, 0x00
|
||||
jne .fail ; unknown device
|
||||
xor eax,eax
|
||||
ret
|
||||
|
||||
.fail:
|
||||
or eax,-1
|
||||
ret
|
||||
|
||||
try_mode_ID3:
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xC8 ;200d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0x64 ;100d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0x50 ;80d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
|
||||
mov al, 0xF2 ;Get device id
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
|
||||
call mouse_read
|
||||
jc .fail
|
||||
cmp al, 0x03
|
||||
jne .fail
|
||||
|
||||
xor eax,eax
|
||||
ret
|
||||
.fail:
|
||||
or eax,-1
|
||||
ret
|
||||
|
||||
try_mode_ID4:
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xC8 ;200d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xC8 ;100d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0xF3 ;Set Sample Rate
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
mov al, 0x50 ;80d
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
|
||||
mov al, 0xF2 ;Get device id
|
||||
call mouse_cmd
|
||||
jc .fail
|
||||
|
||||
call mouse_read
|
||||
jc .fail
|
||||
cmp al, 0x04
|
||||
jne .fail
|
||||
|
||||
xor eax,eax
|
||||
ret
|
||||
|
||||
.fail:
|
||||
or eax,-1
|
||||
ret
|
||||
|
||||
include 'ps2m_iofuncs.inc'
|
||||
include 'ps2m_irqh.inc'
|
||||
|
||||
section '.data' data readable writable align 16
|
||||
|
||||
version dd 0x00050005
|
||||
my_service db 'ps2mouse',0
|
||||
|
||||
;iofuncs data
|
||||
mouse_cmd_byte db 0
|
||||
mouse_nr_tries db 0
|
||||
mouse_nr_resends db 0
|
||||
|
||||
;hid data
|
||||
mouse_byte dd 0
|
||||
|
||||
first_byte db 0
|
||||
second_byte db 0
|
||||
third_byte db 0
|
||||
fourth_byte db 0
|
||||
|
||||
;main data
|
||||
MouseType dd 0
|
||||
|
||||
XMoving dd 0
|
||||
YMoving dd 0
|
||||
ZMoving dd 0
|
||||
ButtonState dd 0
|
||||
;timerTicks dd 0
|
||||
268
drivers/proc32.inc
Normal file
268
drivers/proc32.inc
Normal file
@@ -0,0 +1,268 @@
|
||||
|
||||
; Macroinstructions for defining and calling procedures
|
||||
|
||||
macro stdcall proc,[arg] ; directly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call proc }
|
||||
|
||||
macro invoke proc,[arg] ; indirectly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call [proc] }
|
||||
|
||||
macro ccall proc,[arg] ; directly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call proc
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call [proc]
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro proc [args] ; define procedure
|
||||
{ common
|
||||
match name params, args>
|
||||
\{ define@proc name,<params \} }
|
||||
|
||||
prologue@proc equ prologuedef
|
||||
|
||||
macro prologuedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ if parmbytes | localbytes
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
if localbytes
|
||||
sub esp,localbytes
|
||||
end if
|
||||
end if
|
||||
irps reg, reglist \{ push reg \} }
|
||||
|
||||
epilogue@proc equ epiloguedef
|
||||
|
||||
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ irps reg, reglist \{ reverse pop reg \}
|
||||
if parmbytes | localbytes
|
||||
leave
|
||||
end if
|
||||
if (flag and 10000b) | (parmbytes=0)
|
||||
retn
|
||||
else
|
||||
retn parmbytes
|
||||
end if }
|
||||
|
||||
macro define@proc name,statement
|
||||
{ local params,flag,regs,parmbytes,localbytes,current
|
||||
if used name
|
||||
name:
|
||||
match =stdcall args, statement \{ params equ args
|
||||
flag = 11b \}
|
||||
match =stdcall, statement \{ params equ
|
||||
flag = 11b \}
|
||||
match =c args, statement \{ params equ args
|
||||
flag = 10001b \}
|
||||
match =c, statement \{ params equ
|
||||
flag = 10001b \}
|
||||
match =params, params \{ params equ statement
|
||||
flag = 0 \}
|
||||
virtual at ebp+8
|
||||
match =uses reglist=,args, params \{ regs equ reglist
|
||||
params equ args \}
|
||||
match =regs =uses reglist, regs params \{ regs equ reglist
|
||||
params equ \}
|
||||
match =regs, regs \{ regs equ \}
|
||||
match =,args, params \{ defargs@proc args \}
|
||||
match =args@proc args, args@proc params \{ defargs@proc args \}
|
||||
parmbytes = $ - (ebp+8)
|
||||
end virtual
|
||||
name # % = parmbytes/4
|
||||
all@vars equ
|
||||
current = 0
|
||||
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
|
||||
macro locals
|
||||
\{ virtual at ebp-localbytes+current
|
||||
macro label . \\{ deflocal@proc .,:, \\}
|
||||
struc db [val] \\{ \common deflocal@proc .,db,val \\}
|
||||
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
|
||||
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
|
||||
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
|
||||
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
|
||||
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
|
||||
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
|
||||
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
|
||||
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
|
||||
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
|
||||
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
|
||||
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
|
||||
macro endl
|
||||
\{ purge label
|
||||
restruc db,dw,dp,dd,dt,dq
|
||||
restruc rb,rw,rp,rd,rt,rq
|
||||
restruc byte,word,dword,pword,tword,qword
|
||||
current = $-(ebp-localbytes)
|
||||
end virtual \}
|
||||
macro ret operand
|
||||
\{ match any, operand \\{ retn operand \\}
|
||||
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
|
||||
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
|
||||
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
|
||||
end if \} }
|
||||
|
||||
macro defargs@proc [arg]
|
||||
{ common
|
||||
if ~ arg eq
|
||||
forward
|
||||
local ..arg,current@arg
|
||||
match argname:type, arg
|
||||
\{ current@arg equ argname
|
||||
label ..arg type
|
||||
argname equ ..arg
|
||||
if dqword eq type
|
||||
dd ?,?,?,?
|
||||
else if tbyte eq type
|
||||
dd ?,?,?
|
||||
else if qword eq type | pword eq type
|
||||
dd ?,?
|
||||
else
|
||||
dd ?
|
||||
end if \}
|
||||
match =current@arg,current@arg
|
||||
\{ current@arg equ arg
|
||||
arg equ ..arg
|
||||
..arg dd ? \}
|
||||
common
|
||||
args@proc equ current@arg
|
||||
forward
|
||||
restore current@arg
|
||||
common
|
||||
end if }
|
||||
|
||||
macro deflocal@proc name,def,[val]
|
||||
{ common
|
||||
match vars, all@vars \{ all@vars equ all@vars, \}
|
||||
all@vars equ all@vars name
|
||||
forward
|
||||
local ..var,..tmp
|
||||
..var def val
|
||||
match =?, val \{ ..tmp equ \}
|
||||
match any =dup (=?), val \{ ..tmp equ \}
|
||||
match tmp : value, ..tmp : val
|
||||
\{ tmp: end virtual
|
||||
initlocal@proc ..var,def value
|
||||
virtual at tmp\}
|
||||
common
|
||||
match first rest, ..var, \{ name equ first \} }
|
||||
|
||||
macro initlocal@proc name,def
|
||||
{ virtual at name
|
||||
def
|
||||
size@initlocal = $ - name
|
||||
end virtual
|
||||
position@initlocal = 0
|
||||
while size@initlocal > position@initlocal
|
||||
virtual at name
|
||||
def
|
||||
if size@initlocal - position@initlocal < 2
|
||||
current@initlocal = 1
|
||||
load byte@initlocal byte from name+position@initlocal
|
||||
else if size@initlocal - position@initlocal < 4
|
||||
current@initlocal = 2
|
||||
load word@initlocal word from name+position@initlocal
|
||||
else
|
||||
current@initlocal = 4
|
||||
load dword@initlocal dword from name+position@initlocal
|
||||
end if
|
||||
end virtual
|
||||
if current@initlocal = 1
|
||||
mov byte [name+position@initlocal],byte@initlocal
|
||||
else if current@initlocal = 2
|
||||
mov word [name+position@initlocal],word@initlocal
|
||||
else
|
||||
mov dword [name+position@initlocal],dword@initlocal
|
||||
end if
|
||||
position@initlocal = position@initlocal + current@initlocal
|
||||
end while }
|
||||
|
||||
macro endp
|
||||
{ purge ret,locals,endl
|
||||
finish@proc
|
||||
purge finish@proc
|
||||
restore regs@proc
|
||||
match all,args@proc \{ restore all \}
|
||||
restore args@proc
|
||||
match all,all@vars \{ restore all \} }
|
||||
|
||||
macro local [var]
|
||||
{ common
|
||||
locals
|
||||
forward done@local equ
|
||||
match varname[count]:vartype, var
|
||||
\{ match =BYTE, vartype \\{ varname rb count
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname rw count
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname rd count
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname rp count
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname rq count
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname rt count
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
rq count+count
|
||||
restore done@local \\}
|
||||
match , done@local \\{ virtual
|
||||
varname vartype
|
||||
end virtual
|
||||
rb count*sizeof.\#vartype
|
||||
restore done@local \\} \}
|
||||
match :varname:vartype, done@local:var
|
||||
\{ match =BYTE, vartype \\{ varname db ?
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname dw ?
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname dd ?
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname dp ?
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname dq ?
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname dt ?
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match , done@local \\{ varname vartype
|
||||
restore done@local \\} \}
|
||||
match ,done@local
|
||||
\{ var
|
||||
restore done@local \}
|
||||
common
|
||||
endl }
|
||||
577
drivers/usb/uhci/ch9.h
Normal file
577
drivers/usb/uhci/ch9.h
Normal file
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* This file holds USB constants and structures that are needed for
|
||||
* USB device APIs. These are used by the USB device model, which is
|
||||
* defined in chapter 9 of the USB 2.0 specification and in the
|
||||
* Wireless USB 1.0 (spread around). Linux has several APIs in C that
|
||||
* need these:
|
||||
*
|
||||
* - the master/host side Linux-USB kernel driver API;
|
||||
* - the "usbfs" user space API; and
|
||||
* - the Linux "gadget" slave/device/peripheral side driver API.
|
||||
*
|
||||
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
|
||||
* act either as a USB master/host or as a USB slave/device. That means
|
||||
* the master and slave side APIs benefit from working well together.
|
||||
*
|
||||
* There's also "Wireless USB", using low power short range radios for
|
||||
* peripheral interconnection but otherwise building on the USB framework.
|
||||
*
|
||||
* Note all descriptors are declared '__attribute__((packed))' so that:
|
||||
*
|
||||
* [a] they never get padded, either internally (USB spec writers
|
||||
* probably handled that) or externally;
|
||||
*
|
||||
* [b] so that accessing bigger-than-a-bytes fields will never
|
||||
* generate bus errors on any platform, even when the location of
|
||||
* its descriptor inside a bundle isn't "naturally aligned", and
|
||||
*
|
||||
* [c] for consistency, removing all doubt even when it appears to
|
||||
* someone that the two other points are non-issues for that
|
||||
* particular descriptor type.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_CH9_H
|
||||
#define __LINUX_USB_CH9_H
|
||||
|
||||
#include <linux/types.h> /* __u8 etc */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* CONTROL REQUEST SUPPORT */
|
||||
|
||||
/*
|
||||
* USB directions
|
||||
*
|
||||
* This bit flag is used in endpoint descriptors' bEndpointAddress field.
|
||||
* It's also one of three fields in control requests bRequestType.
|
||||
*/
|
||||
#define USB_DIR_OUT 0 /* to device */
|
||||
#define USB_DIR_IN 0x80 /* to host */
|
||||
|
||||
/*
|
||||
* USB types, the second of three bRequestType fields
|
||||
*/
|
||||
#define USB_TYPE_MASK (0x03 << 5)
|
||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
||||
|
||||
/*
|
||||
* USB recipients, the third of three bRequestType fields
|
||||
*/
|
||||
#define USB_RECIP_MASK 0x1f
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
/* From Wireless USB 1.0 */
|
||||
#define USB_RECIP_PORT 0x04
|
||||
#define USB_RECIP_RPIPE 0x05
|
||||
|
||||
/*
|
||||
* Standard requests, for the bRequest field of a SETUP packet.
|
||||
*
|
||||
* These are qualified by the bRequestType field, so that for example
|
||||
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
|
||||
* by a GET_STATUS request.
|
||||
*/
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */
|
||||
#define USB_REQ_GET_ENCRYPTION 0x0E
|
||||
#define USB_REQ_RPIPE_ABORT 0x0E
|
||||
#define USB_REQ_SET_HANDSHAKE 0x0F
|
||||
#define USB_REQ_RPIPE_RESET 0x0F
|
||||
#define USB_REQ_GET_HANDSHAKE 0x10
|
||||
#define USB_REQ_SET_CONNECTION 0x11
|
||||
#define USB_REQ_SET_SECURITY_DATA 0x12
|
||||
#define USB_REQ_GET_SECURITY_DATA 0x13
|
||||
#define USB_REQ_SET_WUSB_DATA 0x14
|
||||
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
|
||||
#define USB_REQ_LOOPBACK_DATA_READ 0x16
|
||||
#define USB_REQ_SET_INTERFACE_DS 0x17
|
||||
|
||||
/*
|
||||
* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
|
||||
* are read as a bit array returned by USB_REQ_GET_STATUS. (So there
|
||||
* are at most sixteen features of each type.)
|
||||
*/
|
||||
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
|
||||
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
|
||||
#define USB_DEVICE_BATTERY 2 /* (wireless) */
|
||||
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
|
||||
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
|
||||
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
|
||||
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
|
||||
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
|
||||
|
||||
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
|
||||
|
||||
|
||||
/**
|
||||
* struct usb_ctrlrequest - SETUP data for a USB device control request
|
||||
* @bRequestType: matches the USB bmRequestType field
|
||||
* @bRequest: matches the USB bRequest field
|
||||
* @wValue: matches the USB wValue field (le16 byte order)
|
||||
* @wIndex: matches the USB wIndex field (le16 byte order)
|
||||
* @wLength: matches the USB wLength field (le16 byte order)
|
||||
*
|
||||
* This structure is used to send control requests to a USB device. It matches
|
||||
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
|
||||
* USB spec for a fuller description of the different fields, and what they are
|
||||
* used for.
|
||||
*
|
||||
* Note that the driver for any interface can issue control requests.
|
||||
* For most devices, interfaces don't coordinate with each other, so
|
||||
* such requests may be made at any time.
|
||||
*/
|
||||
struct usb_ctrlrequest {
|
||||
__u8 bRequestType;
|
||||
__u8 bRequest;
|
||||
__le16 wValue;
|
||||
__le16 wIndex;
|
||||
__le16 wLength;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
|
||||
* (rarely) accepted by SET_DESCRIPTOR.
|
||||
*
|
||||
* Note that all multi-byte values here are encoded in little endian
|
||||
* byte order "on the wire". But when exposed through Linux-USB APIs,
|
||||
* they've been converted to cpu byte order.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Descriptor types ... USB 2.0 spec table 9.5
|
||||
*/
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
#define USB_DT_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DT_OTHER_SPEED_CONFIG 0x07
|
||||
#define USB_DT_INTERFACE_POWER 0x08
|
||||
/* these are from a minor usb 2.0 revision (ECN) */
|
||||
#define USB_DT_OTG 0x09
|
||||
#define USB_DT_DEBUG 0x0a
|
||||
#define USB_DT_INTERFACE_ASSOCIATION 0x0b
|
||||
/* these are from the Wireless USB spec */
|
||||
#define USB_DT_SECURITY 0x0c
|
||||
#define USB_DT_KEY 0x0d
|
||||
#define USB_DT_ENCRYPTION_TYPE 0x0e
|
||||
#define USB_DT_BOS 0x0f
|
||||
#define USB_DT_DEVICE_CAPABILITY 0x10
|
||||
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
|
||||
#define USB_DT_WIRE_ADAPTER 0x21
|
||||
#define USB_DT_RPIPE 0x22
|
||||
|
||||
/* conventional codes for class-specific descriptors */
|
||||
#define USB_DT_CS_DEVICE 0x21
|
||||
#define USB_DT_CS_CONFIG 0x22
|
||||
#define USB_DT_CS_STRING 0x23
|
||||
#define USB_DT_CS_INTERFACE 0x24
|
||||
#define USB_DT_CS_ENDPOINT 0x25
|
||||
|
||||
/* All standard descriptors have these 2 fields at the beginning */
|
||||
struct usb_descriptor_header {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_DEVICE: Device descriptor */
|
||||
struct usb_device_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 bcdUSB;
|
||||
__u8 bDeviceClass;
|
||||
__u8 bDeviceSubClass;
|
||||
__u8 bDeviceProtocol;
|
||||
__u8 bMaxPacketSize0;
|
||||
__le16 idVendor;
|
||||
__le16 idProduct;
|
||||
__le16 bcdDevice;
|
||||
__u8 iManufacturer;
|
||||
__u8 iProduct;
|
||||
__u8 iSerialNumber;
|
||||
__u8 bNumConfigurations;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USB_DT_DEVICE_SIZE 18
|
||||
|
||||
|
||||
/*
|
||||
* Device and/or Interface Class codes
|
||||
* as found in bDeviceClass or bInterfaceClass
|
||||
* and defined by www.usb.org documents
|
||||
*/
|
||||
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PHYSICAL 5
|
||||
#define USB_CLASS_STILL_IMAGE 6
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_CDC_DATA 0x0a
|
||||
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
|
||||
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
|
||||
#define USB_CLASS_VIDEO 0x0e
|
||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
||||
#define USB_CLASS_MISC 0xef
|
||||
#define USB_CLASS_APP_SPEC 0xfe
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_CONFIG: Configuration descriptor information.
|
||||
*
|
||||
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
|
||||
* descriptor type is different. Highspeed-capable devices can look
|
||||
* different depending on what speed they're currently running. Only
|
||||
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
|
||||
* descriptors.
|
||||
*/
|
||||
struct usb_config_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 wTotalLength;
|
||||
__u8 bNumInterfaces;
|
||||
__u8 bConfigurationValue;
|
||||
__u8 iConfiguration;
|
||||
__u8 bmAttributes;
|
||||
__u8 bMaxPower;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USB_DT_CONFIG_SIZE 9
|
||||
|
||||
/* from config descriptor bmAttributes */
|
||||
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
|
||||
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
|
||||
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
|
||||
#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_STRING: String descriptor */
|
||||
struct usb_string_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 wData[1]; /* UTF-16LE encoded */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* note that "string" zero is special, it holds language codes that
|
||||
* the device supports, not Unicode characters.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_INTERFACE: Interface descriptor */
|
||||
struct usb_interface_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bInterfaceNumber;
|
||||
__u8 bAlternateSetting;
|
||||
__u8 bNumEndpoints;
|
||||
__u8 bInterfaceClass;
|
||||
__u8 bInterfaceSubClass;
|
||||
__u8 bInterfaceProtocol;
|
||||
__u8 iInterface;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USB_DT_INTERFACE_SIZE 9
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_ENDPOINT: Endpoint descriptor */
|
||||
struct usb_endpoint_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bEndpointAddress;
|
||||
__u8 bmAttributes;
|
||||
__le16 wMaxPacketSize;
|
||||
__u8 bInterval;
|
||||
|
||||
/* NOTE: these two are _only_ in audio endpoints. */
|
||||
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
|
||||
__u8 bRefresh;
|
||||
__u8 bSynchAddress;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USB_DT_ENDPOINT_SIZE 7
|
||||
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
|
||||
|
||||
|
||||
/*
|
||||
* Endpoints
|
||||
*/
|
||||
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
|
||||
#define USB_ENDPOINT_DIR_MASK 0x80
|
||||
|
||||
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
|
||||
#define USB_ENDPOINT_XFER_CONTROL 0
|
||||
#define USB_ENDPOINT_XFER_ISOC 1
|
||||
#define USB_ENDPOINT_XFER_BULK 2
|
||||
#define USB_ENDPOINT_XFER_INT 3
|
||||
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
|
||||
struct usb_qualifier_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 bcdUSB;
|
||||
__u8 bDeviceClass;
|
||||
__u8 bDeviceSubClass;
|
||||
__u8 bDeviceProtocol;
|
||||
__u8 bMaxPacketSize0;
|
||||
__u8 bNumConfigurations;
|
||||
__u8 bRESERVED;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_OTG (from OTG 1.0a supplement) */
|
||||
struct usb_otg_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bmAttributes; /* support for HNP, SRP, etc */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* from usb_otg_descriptor.bmAttributes */
|
||||
#define USB_OTG_SRP (1 << 0)
|
||||
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
|
||||
struct usb_debug_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
/* bulk endpoints with 8 byte maxpacket */
|
||||
__u8 bDebugInEndpoint;
|
||||
__u8 bDebugOutEndpoint;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
|
||||
struct usb_interface_assoc_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bFirstInterface;
|
||||
__u8 bInterfaceCount;
|
||||
__u8 bFunctionClass;
|
||||
__u8 bFunctionSubClass;
|
||||
__u8 bFunctionProtocol;
|
||||
__u8 iFunction;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_SECURITY: group of wireless security descriptors, including
|
||||
* encryption types available for setting up a CC/association.
|
||||
*/
|
||||
struct usb_security_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 wTotalLength;
|
||||
__u8 bNumEncryptionTypes;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys
|
||||
* may be retrieved.
|
||||
*/
|
||||
struct usb_key_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 tTKID[3];
|
||||
__u8 bReserved;
|
||||
__u8 bKeyData[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */
|
||||
struct usb_encryption_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bEncryptionType;
|
||||
#define USB_ENC_TYPE_UNSECURE 0
|
||||
#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */
|
||||
#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */
|
||||
#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
|
||||
__u8 bEncryptionValue; /* use in SET_ENCRYPTION */
|
||||
__u8 bAuthKeyIndex;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_BOS: group of wireless capabilities */
|
||||
struct usb_bos_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__le16 wTotalLength;
|
||||
__u8 bNumDeviceCaps;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */
|
||||
struct usb_dev_cap_header {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDevCapabilityType;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define USB_CAP_TYPE_WIRELESS_USB 1
|
||||
|
||||
struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDevCapabilityType;
|
||||
|
||||
__u8 bmAttributes;
|
||||
#define USB_WIRELESS_P2P_DRD (1 << 1)
|
||||
#define USB_WIRELESS_BEACON_MASK (3 << 2)
|
||||
#define USB_WIRELESS_BEACON_SELF (1 << 2)
|
||||
#define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
|
||||
#define USB_WIRELESS_BEACON_NONE (3 << 2)
|
||||
__le16 wPHYRates; /* bit rates, Mbps */
|
||||
#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */
|
||||
#define USB_WIRELESS_PHY_80 (1 << 1)
|
||||
#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */
|
||||
#define USB_WIRELESS_PHY_160 (1 << 3)
|
||||
#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */
|
||||
#define USB_WIRELESS_PHY_320 (1 << 5)
|
||||
#define USB_WIRELESS_PHY_400 (1 << 6)
|
||||
#define USB_WIRELESS_PHY_480 (1 << 7)
|
||||
__u8 bmTFITXPowerInfo; /* TFI power levels */
|
||||
__u8 bmFFITXPowerInfo; /* FFI power levels */
|
||||
__le16 bmBandGroup;
|
||||
__u8 bReserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with
|
||||
* each endpoint descriptor for a wireless device
|
||||
*/
|
||||
struct usb_wireless_ep_comp_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
|
||||
__u8 bMaxBurst;
|
||||
__u8 bMaxSequence;
|
||||
__le16 wMaxStreamDelay;
|
||||
__le16 wOverTheAirPacketSize;
|
||||
__u8 bOverTheAirInterval;
|
||||
__u8 bmCompAttributes;
|
||||
#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */
|
||||
#define USB_ENDPOINT_SWITCH_NO 0
|
||||
#define USB_ENDPOINT_SWITCH_SWITCH 1
|
||||
#define USB_ENDPOINT_SWITCH_SCALE 2
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
|
||||
* host and a device for connection set up, mutual authentication, and
|
||||
* exchanging short lived session keys. The handshake depends on a CC.
|
||||
*/
|
||||
struct usb_handshake {
|
||||
__u8 bMessageNumber;
|
||||
__u8 bStatus;
|
||||
__u8 tTKID[3];
|
||||
__u8 bReserved;
|
||||
__u8 CDID[16];
|
||||
__u8 nonce[16];
|
||||
__u8 MIC[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
|
||||
* A CC may also be set up using non-wireless secure channels (including
|
||||
* wired USB!), and some devices may support CCs with multiple hosts.
|
||||
*/
|
||||
struct usb_connection_context {
|
||||
__u8 CHID[16]; /* persistent host id */
|
||||
__u8 CDID[16]; /* device id (unique w/in host context) */
|
||||
__u8 CK[16]; /* connection key */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB 2.0 defines three speeds, here's how Linux identifies them */
|
||||
|
||||
enum usb_device_speed {
|
||||
USB_SPEED_UNKNOWN = 0, /* enumerating */
|
||||
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
|
||||
USB_SPEED_HIGH, /* usb 2.0 */
|
||||
USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
|
||||
};
|
||||
|
||||
enum usb_device_state {
|
||||
/* NOTATTACHED isn't in the USB spec, and this state acts
|
||||
* the same as ATTACHED ... but it's clearer this way.
|
||||
*/
|
||||
USB_STATE_NOTATTACHED = 0,
|
||||
|
||||
/* chapter 9 and authentication (wireless) device states */
|
||||
USB_STATE_ATTACHED,
|
||||
USB_STATE_POWERED, /* wired */
|
||||
USB_STATE_UNAUTHENTICATED, /* auth */
|
||||
USB_STATE_RECONNECTING, /* auth */
|
||||
USB_STATE_DEFAULT, /* limited function */
|
||||
USB_STATE_ADDRESS,
|
||||
USB_STATE_CONFIGURED, /* most functions */
|
||||
|
||||
USB_STATE_SUSPENDED
|
||||
|
||||
/* NOTE: there are actually four different SUSPENDED
|
||||
* states, returning to POWERED, DEFAULT, ADDRESS, or
|
||||
* CONFIGURED respectively when SOF tokens flow again.
|
||||
*/
|
||||
};
|
||||
|
||||
#endif /* __LINUX_USB_CH9_H */
|
||||
63
drivers/usb/uhci/detect.inc
Normal file
63
drivers/usb/uhci/detect.inc
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
|
||||
static Bool FindPciDevice()
|
||||
{
|
||||
Bool retval = FALSE;
|
||||
u32_t bus, last_bus;
|
||||
PCITAG tag;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return retval;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
hc_t *hc;
|
||||
|
||||
u32_t id;
|
||||
u16_t pcicmd;
|
||||
u16_t devclass;
|
||||
int i;
|
||||
|
||||
devclass = PciRead16(bus,devfn, 0x0A);
|
||||
|
||||
if( devclass != 0x0C03)
|
||||
continue;
|
||||
|
||||
pcicmd = PciRead16(bus,devfn, PCI_COMMAND);
|
||||
if (! pcicmd & PCI_COMMAND_IO)
|
||||
continue;
|
||||
|
||||
hc = (hc_t*)malloc(sizeof(hc_t));
|
||||
memset(hc, 0, sizeof(hc_t));
|
||||
link_initialize(&hc->link);
|
||||
|
||||
hc->pciId = PciRead32(bus,devfn, 0);
|
||||
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
u32_t base;
|
||||
Bool validSize;
|
||||
|
||||
base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
|
||||
if(base)
|
||||
{
|
||||
if (base & PCI_MAP_IO) {
|
||||
hc->ioBase[i] = (addr_t)PCIGETIO(base);
|
||||
hc->memType[i] = base & PCI_MAP_IO_ATTR_MASK;
|
||||
} else {
|
||||
hc->memBase[i] = (u32_t)PCIGETMEMORY(base);
|
||||
hc->memType[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
list_prepend(&hc->link, &hc_list);
|
||||
retval = TRUE;
|
||||
};
|
||||
};
|
||||
return retval;
|
||||
};
|
||||
604
drivers/usb/uhci/hcd.inc
Normal file
604
drivers/usb/uhci/hcd.inc
Normal file
@@ -0,0 +1,604 @@
|
||||
|
||||
#define UHCI_USBLEGSUP 0x00c0 /* legacy support */
|
||||
#define UHCI_USBCMD 0 /* command register */
|
||||
#define UHCI_USBINTR 4 /* interrupt register */
|
||||
#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
|
||||
#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
|
||||
#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */
|
||||
#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */
|
||||
#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */
|
||||
#define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */
|
||||
#define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */
|
||||
|
||||
|
||||
#define USBCMD 0
|
||||
#define USBCMD_RS 0x0001 /* Run/Stop */
|
||||
#define USBCMD_HCRESET 0x0002 /* Host reset */
|
||||
#define USBCMD_GRESET 0x0004 /* Global reset */
|
||||
#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
|
||||
#define USBCMD_FGR 0x0010 /* Force Global Resume */
|
||||
#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
|
||||
#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
|
||||
#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
|
||||
|
||||
#define USBSTS 2
|
||||
#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
|
||||
#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
|
||||
#define USBSTS_RD 0x0004 /* Resume Detect */
|
||||
#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */
|
||||
#define USBSTS_HCPE 0x0010 /* Host Controller Process Error:
|
||||
* the schedule is buggy */
|
||||
#define USBSTS_HCH 0x0020 /* HC Halted */
|
||||
|
||||
|
||||
#define USBFRNUM 6
|
||||
#define USBFLBASEADD 8
|
||||
#define USBSOF 12
|
||||
#define USBSOF_DEFAULT 64 /* Frame length is exactly 1 ms */
|
||||
|
||||
#define USBPORTSC1 16
|
||||
#define USBPORTSC2 18
|
||||
|
||||
#define UHCI_RH_MAXCHILD 7
|
||||
|
||||
|
||||
/*
|
||||
* Make sure the controller is completely inactive, unable to
|
||||
* generate interrupts or do DMA.
|
||||
*/
|
||||
void uhci_reset_hc(hc_t *hc)
|
||||
{
|
||||
/* Turn off PIRQ enable and SMI enable. (This also turns off the
|
||||
* BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
|
||||
*/
|
||||
pciWriteWord(hc->PciTag, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC);
|
||||
|
||||
/* Reset the HC - this will force us to get a
|
||||
* new notification of any already connected
|
||||
* ports due to the virtual disconnect that it
|
||||
* implies.
|
||||
*/
|
||||
out16(hc->iobase + UHCI_USBCMD, UHCI_USBCMD_HCRESET);
|
||||
__asm__ __volatile__ ("":::"memory");
|
||||
|
||||
delay(20/10);
|
||||
|
||||
if (in16(hc->iobase + UHCI_USBCMD) & UHCI_USBCMD_HCRESET)
|
||||
dbgprintf("HCRESET not completed yet!\n");
|
||||
|
||||
/* Just to be safe, disable interrupt requests and
|
||||
* make sure the controller is stopped.
|
||||
*/
|
||||
out16(hc->iobase + UHCI_USBINTR, 0);
|
||||
out16(hc->iobase + UHCI_USBCMD, 0);
|
||||
};
|
||||
|
||||
int uhci_check_and_reset_hc(hc_t *hc)
|
||||
{
|
||||
u16_t legsup;
|
||||
unsigned int cmd, intr;
|
||||
|
||||
/*
|
||||
* When restarting a suspended controller, we expect all the
|
||||
* settings to be the same as we left them:
|
||||
*
|
||||
* PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
|
||||
* Controller is stopped and configured with EGSM set;
|
||||
* No interrupts enabled except possibly Resume Detect.
|
||||
*
|
||||
* If any of these conditions are violated we do a complete reset.
|
||||
*/
|
||||
legsup = pciReadWord(hc->PciTag, UHCI_USBLEGSUP);
|
||||
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
|
||||
dbgprintf("%s: legsup = 0x%04x\n",__FUNCTION__, legsup);
|
||||
goto reset_needed;
|
||||
}
|
||||
|
||||
cmd = in16(hc->iobase + UHCI_USBCMD);
|
||||
if ( (cmd & UHCI_USBCMD_RUN) ||
|
||||
!(cmd & UHCI_USBCMD_CONFIGURE) ||
|
||||
!(cmd & UHCI_USBCMD_EGSM))
|
||||
{
|
||||
dbgprintf("%s: cmd = 0x%04x\n", __FUNCTION__, cmd);
|
||||
goto reset_needed;
|
||||
}
|
||||
|
||||
intr = in16(hc->iobase + UHCI_USBINTR);
|
||||
if (intr & (~UHCI_USBINTR_RESUME))
|
||||
{
|
||||
dbgprintf("%s: intr = 0x%04x\n", __FUNCTION__, intr);
|
||||
goto reset_needed;
|
||||
}
|
||||
return 0;
|
||||
|
||||
reset_needed:
|
||||
dbgprintf("Performing full reset\n");
|
||||
uhci_reset_hc(hc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Bool init_hc(hc_t *hc)
|
||||
{
|
||||
int port;
|
||||
u32_t ifl;
|
||||
u16_t dev_status;
|
||||
int i;
|
||||
|
||||
dbgprintf("\n\ninit uhci %x\n\n", hc->pciId);
|
||||
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
if(hc->ioBase[i]){
|
||||
hc->iobase = hc->ioBase[i];
|
||||
// dbgprintf("Io base_%d 0x%x\n", i,hc->ioBase[i]);
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
/* The UHCI spec says devices must have 2 ports, and goes on to say
|
||||
* they may have more but gives no way to determine how many there
|
||||
* are. However according to the UHCI spec, Bit 7 of the port
|
||||
* status and control register is always set to 1. So we try to
|
||||
* use this to our advantage. Another common failure mode when
|
||||
* a nonexistent register is addressed is to return all ones, so
|
||||
* we test for that also.
|
||||
*/
|
||||
for (port = 0; port < 2; port++)
|
||||
{
|
||||
u32_t status;
|
||||
|
||||
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
|
||||
dbgprintf("port%d status %x\n", port, status);
|
||||
if (!(status & 0x0080) || status == 0xffff)
|
||||
break;
|
||||
}
|
||||
dbgprintf("detected %d ports\n\n", port);
|
||||
|
||||
hc->numports = port;
|
||||
|
||||
/* Kick BIOS off this hardware and reset if the controller
|
||||
* isn't already safely quiescent.
|
||||
*/
|
||||
uhci_check_and_reset_hc(hc);
|
||||
|
||||
hc->frame_base = (u32_t*)KernelAlloc(4096);
|
||||
hc->frame_dma = GetPgAddr(hc->frame_base);
|
||||
hc->frame_number = 0;
|
||||
|
||||
qh_t *qh = alloc_qh();
|
||||
|
||||
qh->qlink = 1;
|
||||
qh->qelem = 1;
|
||||
|
||||
hc->qh1 = qh;
|
||||
|
||||
// dbgprintf("alloc qh %x dma %x\n", qh, qh->dma);
|
||||
|
||||
for(i=0; i<1024; i++)
|
||||
hc->frame_base[i] = qh->dma | 2;
|
||||
|
||||
|
||||
/* Set the frame length to the default: 1 ms exactly */
|
||||
out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
|
||||
|
||||
/* Store the frame list base address */
|
||||
out32(hc->iobase + USBFLBASEADD, hc->frame_dma);
|
||||
|
||||
/* Set the current frame number */
|
||||
out16(hc->iobase + USBFRNUM, 0);
|
||||
|
||||
out16(hc->iobase + USBSTS, 0x3F);
|
||||
out16(hc->iobase + USBCMD, USBCMD_RS | USBCMD_CF |
|
||||
USBCMD_MAXP);
|
||||
|
||||
for (port = 0; port < hc->numports; ++port)
|
||||
out16(hc->iobase + USBPORTSC1 + (port * 2), 0x200);
|
||||
delay(100/10);
|
||||
|
||||
for (port = 0; port < 2; ++port)
|
||||
{
|
||||
time_t timeout;
|
||||
|
||||
u32_t status = in16(hc->iobase + USBPORTSC1 + (port * 2));
|
||||
dbgprintf("port%d status %x\n", port, status);
|
||||
|
||||
out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
|
||||
|
||||
timeout = 100/10;
|
||||
while(timeout--)
|
||||
{
|
||||
delay(10/10);
|
||||
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
|
||||
if(status & 1)
|
||||
{
|
||||
udev_t *dev = malloc(sizeof(udev_t));
|
||||
|
||||
out16(hc->iobase + USBPORTSC1 + (port * 2), 0x0E);
|
||||
|
||||
delay(20/10);
|
||||
|
||||
dbgprintf("enable port\n");
|
||||
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
|
||||
dbgprintf("port%d status %x\n", port, status);
|
||||
|
||||
link_initialize(&dev->link);
|
||||
dev->id = 0;
|
||||
dev->host = hc;
|
||||
dev->addr = 0;
|
||||
dev->port = port;
|
||||
dev->ep0_size = 8;
|
||||
dev->status = status;
|
||||
|
||||
dbgprintf("port%d connected", port);
|
||||
if(status & 4)
|
||||
dbgprintf(" enabled");
|
||||
else
|
||||
dbgprintf(" disabled");
|
||||
if(status & 0x100){
|
||||
dev->speed = 0x4000000;
|
||||
dbgprintf(" low speed\n");
|
||||
} else {
|
||||
dev->speed = 0;
|
||||
dbgprintf(" full speed\n");
|
||||
};
|
||||
|
||||
if(set_address(dev)) {
|
||||
list_prepend(&dev->link, &newdev_list);
|
||||
hc->port_map |= 1<<port;
|
||||
}
|
||||
else {
|
||||
free(dev);
|
||||
out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
|
||||
}
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
u16_t __attribute__((aligned(16)))
|
||||
req_descr[4] = {0x0680,0x0100,0x0000,8};
|
||||
|
||||
/*
|
||||
IN(69) OUT(E1) SETUP(2D)
|
||||
SETUP(0) IN(1)
|
||||
SETUP(0) OUT(1) OUT(0) OUT(1)...IN(1)
|
||||
SETUP(0) IN(1) IN(0) IN(1)...OUT(0)
|
||||
*/
|
||||
|
||||
|
||||
Bool set_address(udev_t *dev)
|
||||
{
|
||||
static udev_id = 0;
|
||||
static udev_addr = 0;
|
||||
static u16_t __attribute__((aligned(16)))
|
||||
req_addr[4] = {0x0500,0x0001,0x0000,0x0000};
|
||||
|
||||
static u16_t __attribute__((aligned(16)))
|
||||
req_descr[4] = {0x0680,0x0100,0x0000,8};
|
||||
|
||||
static u32_t data[2] __attribute__((aligned(16)));
|
||||
|
||||
qh_t *qh;
|
||||
td_t *td0, *td1, *td2;
|
||||
u32_t dev_status;
|
||||
count_t timeout;
|
||||
int address;
|
||||
|
||||
address = ++udev_addr;
|
||||
|
||||
req_addr[1] = address;
|
||||
|
||||
if( !ctrl_request(dev, &req_addr, DOUT, NULL, 0))
|
||||
return FALSE;
|
||||
|
||||
dev->addr = address;
|
||||
dev->id = (++udev_id << 8) | address;
|
||||
|
||||
dbgprintf("set address %d\n", address);
|
||||
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
|
||||
if( !ctrl_request(dev, &req_descr, DIN, data, 8))
|
||||
return FALSE;
|
||||
|
||||
dev_descr_t *descr = (dev_descr_t*)&data;
|
||||
dev->ep0_size = descr->bMaxPacketSize0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir,
|
||||
void *data, size_t req_size)
|
||||
{
|
||||
td_t *td, *td_prev;
|
||||
addr_t data_dma;
|
||||
|
||||
request_t *rq = (request_t*)malloc(sizeof(request_t));
|
||||
|
||||
link_initialize(&rq->link);
|
||||
|
||||
rq->td_head = 0;
|
||||
rq->td_tail = 0;
|
||||
|
||||
rq->data = (addr_t)data;
|
||||
rq->size = req_size;
|
||||
rq->dev = dev;
|
||||
|
||||
if(data)
|
||||
data_dma = DMA(data);
|
||||
|
||||
td_prev = NULL;
|
||||
|
||||
while(req_size >= enp->size)
|
||||
{
|
||||
td = alloc_td();
|
||||
td->link = 1;
|
||||
|
||||
if(rq->td_head == NULL)
|
||||
rq->td_head = td;
|
||||
|
||||
if( td_prev )
|
||||
td_prev->link = td->dma | 4;
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token = TOKEN(enp->size,enp->toggle,enp->address,
|
||||
dev->addr,dir);
|
||||
td->buffer = data_dma;
|
||||
td->bk = td_prev;
|
||||
|
||||
td_prev = td;
|
||||
|
||||
data_dma+= enp->size;
|
||||
req_size-= enp->size;
|
||||
enp->toggle ^= DATA1;
|
||||
}
|
||||
if(req_size)
|
||||
{
|
||||
td = alloc_td();
|
||||
td->link = 1;
|
||||
|
||||
if(rq->td_head == NULL)
|
||||
rq->td_head = td;
|
||||
|
||||
if( td_prev )
|
||||
td_prev->link = td->dma | 4;
|
||||
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token = TOKEN( req_size, enp->toggle, enp->address,
|
||||
dev->addr, dir);
|
||||
td->buffer = data_dma;
|
||||
td->bk = td_prev;
|
||||
|
||||
enp->toggle ^= DATA1;
|
||||
}
|
||||
rq->td_tail = td;
|
||||
/*
|
||||
dbgprintf("create request %x\n"
|
||||
"head %x\n"
|
||||
"tail %x\n"
|
||||
"data %x\n"
|
||||
"size %x\n",
|
||||
rq, rq->td_head, rq->td_tail,
|
||||
rq->data, rq->size);
|
||||
*/
|
||||
return rq;
|
||||
}
|
||||
|
||||
Bool ctrl_request(udev_t *dev, void *req, u32_t pid,
|
||||
void *data, size_t req_size)
|
||||
{
|
||||
size_t packet_size = dev->ep0_size;
|
||||
size_t size = req_size;
|
||||
u32_t toggle = DATA1;
|
||||
|
||||
td_t *td0, *td, *td_prev;
|
||||
qh_t *qh;
|
||||
addr_t data_dma = 0;
|
||||
Bool retval;
|
||||
|
||||
td0 = alloc_td();
|
||||
|
||||
td0->status = 0x00800000 | dev->speed;
|
||||
td0->token = TOKEN( 8, DATA0, 0, dev->addr, 0x2D);
|
||||
td0->buffer = DMA(req);
|
||||
td0->bk = NULL;
|
||||
|
||||
if(data)
|
||||
data_dma = DMA(data);
|
||||
|
||||
td_prev = td0;
|
||||
|
||||
while(size >= packet_size)
|
||||
{
|
||||
td = alloc_td();
|
||||
td_prev->link = td->dma | 4;
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token = TOKEN(packet_size, toggle, 0,dev->addr, pid);
|
||||
td->buffer = data_dma;
|
||||
td->bk = td_prev;
|
||||
|
||||
td_prev = td;
|
||||
|
||||
data_dma+= packet_size;
|
||||
size-= packet_size;
|
||||
toggle ^= DATA1;
|
||||
}
|
||||
if(size)
|
||||
{
|
||||
td = alloc_td();
|
||||
td_prev->link = td->dma | 4;
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token = ((size-1)<<21)|toggle|(dev->addr<<8)|pid;
|
||||
td->buffer = data_dma;
|
||||
td->bk = td_prev;
|
||||
|
||||
td_prev = td;
|
||||
|
||||
data_dma+= packet_size;
|
||||
size-= packet_size;
|
||||
toggle ^= DATA1;
|
||||
}
|
||||
|
||||
td = alloc_td();
|
||||
td_prev->link = td->dma | 4;
|
||||
|
||||
pid = (pid == DIN) ? DOUT : DIN;
|
||||
|
||||
td->link = 1;
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
|
||||
td->buffer = 0;
|
||||
td->bk = td_prev;
|
||||
|
||||
qh = dev->host->qh1;
|
||||
|
||||
qh->qelem = td0->dma;
|
||||
__asm__ __volatile__ ("":::"memory");
|
||||
|
||||
count_t timeout = 25;
|
||||
while(timeout--){
|
||||
delay(10/10);
|
||||
if( !(td->status & TD_CTRL_ACTIVE))
|
||||
break;
|
||||
}
|
||||
|
||||
if( (td0->status & TD_ANY_ERROR) ||
|
||||
(td_prev->status & TD_ANY_ERROR) ||
|
||||
(td->status & TD_ANY_ERROR))
|
||||
{
|
||||
u32_t dev_status = in16(dev->host->iobase + USBSTS);
|
||||
|
||||
dbgprintf("\nframe %x, cmd %x status %x\n",
|
||||
in16(dev->host->iobase + USBFRNUM),
|
||||
in16(dev->host->iobase + USBCMD),
|
||||
dev_status);
|
||||
dbgprintf("td0 status %x\n",td0->status);
|
||||
dbgprintf("td_prev status %x\n",td_prev->status);
|
||||
dbgprintf("td status %x\n",td->status);
|
||||
dbgprintf("qh %x \n", qh->qelem);
|
||||
|
||||
retval = FALSE;
|
||||
} else retval = TRUE;
|
||||
|
||||
do
|
||||
{
|
||||
td_prev = td->bk;
|
||||
free_td(td);
|
||||
td = td_prev;
|
||||
}while( td != NULL);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
Bool init_device(udev_t *dev)
|
||||
{
|
||||
static u16_t __attribute__((aligned(16)))
|
||||
req_descr[4] = {0x0680,0x0100,0x0000,18};
|
||||
|
||||
static u16_t __attribute__((aligned(16)))
|
||||
req_conf[4] = {0x0680,0x0200,0x0000,9};
|
||||
|
||||
static dev_descr_t __attribute__((aligned(16))) descr;
|
||||
|
||||
interface_descr_t *interface;
|
||||
|
||||
u32_t data[8];
|
||||
|
||||
u8_t *dptr;
|
||||
conf_descr_t *conf;
|
||||
|
||||
dbgprintf("\ninit device %x, host %x, port %d\n\n",
|
||||
dev->id, dev->host->pciId, dev->port);
|
||||
|
||||
if( !ctrl_request(dev, req_descr, DIN, &descr, 18))
|
||||
return;
|
||||
|
||||
dev->dev_descr = descr;
|
||||
|
||||
dbgprintf("device descriptor:\n\n"
|
||||
"bLength %d\n"
|
||||
"bDescriptorType %d\n"
|
||||
"bcdUSB %x\n"
|
||||
"bDeviceClass %x\n"
|
||||
"bDeviceSubClass %x\n"
|
||||
"bDeviceProtocol %x\n"
|
||||
"bMaxPacketSize0 %d\n"
|
||||
"idVendor %x\n"
|
||||
"idProduct %x\n"
|
||||
"bcdDevice %x\n"
|
||||
"iManufacturer %x\n"
|
||||
"iProduct %x\n"
|
||||
"iSerialNumber %x\n"
|
||||
"bNumConfigurations %d\n\n",
|
||||
descr.bLength, descr.bDescriptorType,
|
||||
descr.bcdUSB, descr.bDeviceClass,
|
||||
descr.bDeviceSubClass, descr.bDeviceProtocol,
|
||||
descr.bMaxPacketSize0, descr.idVendor,
|
||||
descr.idProduct, descr.bcdDevice,
|
||||
descr.iManufacturer, descr.iProduct,
|
||||
descr.iSerialNumber, descr.bNumConfigurations);
|
||||
|
||||
req_conf[3] = 8;
|
||||
if( !ctrl_request(dev, req_conf, DIN, &data, 8))
|
||||
return;
|
||||
|
||||
conf = (conf_descr_t*)&data;
|
||||
|
||||
size_t conf_size = conf->wTotalLength;
|
||||
|
||||
req_conf[3] = conf_size;
|
||||
conf = malloc(conf_size);
|
||||
|
||||
if( !ctrl_request(dev, req_conf, DIN, conf, conf_size))
|
||||
return;
|
||||
|
||||
dptr = (u8_t*)conf;
|
||||
dptr+= conf->bLength;
|
||||
|
||||
dbgprintf("configuration descriptor\n\n"
|
||||
"bLength %d\n"
|
||||
"bDescriptorType %d\n"
|
||||
"wTotalLength %d\n"
|
||||
"bNumInterfaces %d\n"
|
||||
"bConfigurationValue %x\n"
|
||||
"iConfiguration %d\n"
|
||||
"bmAttributes %x\n"
|
||||
"bMaxPower %dmA\n\n",
|
||||
conf->bLength,
|
||||
conf->bDescriptorType,
|
||||
conf->wTotalLength,
|
||||
conf->bNumInterfaces,
|
||||
conf->bConfigurationValue,
|
||||
conf->iConfiguration,
|
||||
conf->bmAttributes,
|
||||
conf->bMaxPower*2);
|
||||
|
||||
interface = (interface_descr_t*)dptr;
|
||||
|
||||
switch(interface->bInterfaceClass)
|
||||
{
|
||||
case USB_CLASS_AUDIO:
|
||||
dbgprintf( "audio device\n");
|
||||
break;
|
||||
case USB_CLASS_HID:
|
||||
dev->conf = conf;
|
||||
list_remove(&dev->link);
|
||||
return init_hid(dev);
|
||||
|
||||
case USB_CLASS_PRINTER:
|
||||
dbgprintf("printer\n");
|
||||
break;
|
||||
case USB_CLASS_MASS_STORAGE:
|
||||
dbgprintf("mass storage device\n");
|
||||
break;
|
||||
case USB_CLASS_HUB:
|
||||
dbgprintf("hub device\n");
|
||||
break;
|
||||
default:
|
||||
dbgprintf("unknown device\n");
|
||||
};
|
||||
};
|
||||
523
drivers/usb/uhci/hid.h
Normal file
523
drivers/usb/uhci/hid.h
Normal file
@@ -0,0 +1,523 @@
|
||||
#ifndef __HID_H
|
||||
#define __HID_H
|
||||
|
||||
/*
|
||||
* $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999 Andreas Gal
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
* Copyright (c) 2006-2007 Jiri Kosina
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Should you need to contact me, the author, you can do so either by
|
||||
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
|
||||
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
/*
|
||||
* USB HID (Human Interface Device) interface class code
|
||||
*/
|
||||
|
||||
#define USB_INTERFACE_CLASS_HID 3
|
||||
|
||||
/*
|
||||
* USB HID interface subclass and protocol codes
|
||||
*/
|
||||
|
||||
#define USB_INTERFACE_SUBCLASS_BOOT 1
|
||||
#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
|
||||
#define USB_INTERFACE_PROTOCOL_MOUSE 2
|
||||
|
||||
/*
|
||||
* HID class requests
|
||||
*/
|
||||
|
||||
#define HID_REQ_GET_REPORT 0x01
|
||||
#define HID_REQ_GET_IDLE 0x02
|
||||
#define HID_REQ_GET_PROTOCOL 0x03
|
||||
#define HID_REQ_SET_REPORT 0x09
|
||||
#define HID_REQ_SET_IDLE 0x0A
|
||||
#define HID_REQ_SET_PROTOCOL 0x0B
|
||||
|
||||
/*
|
||||
* HID class descriptor types
|
||||
*/
|
||||
|
||||
#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
|
||||
#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
|
||||
#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
|
||||
|
||||
/*
|
||||
* We parse each description item into this structure. Short items data
|
||||
* values are expanded to 32-bit signed int, long items contain a pointer
|
||||
* into the data area.
|
||||
*/
|
||||
|
||||
struct hid_item {
|
||||
unsigned format;
|
||||
__u8 size;
|
||||
__u8 type;
|
||||
__u8 tag;
|
||||
union {
|
||||
__u8 u8;
|
||||
__s8 s8;
|
||||
__u16 u16;
|
||||
__s16 s16;
|
||||
__u32 u32;
|
||||
__s32 s32;
|
||||
__u8 *longdata;
|
||||
} data;
|
||||
};
|
||||
|
||||
/*
|
||||
* HID report item format
|
||||
*/
|
||||
|
||||
#define HID_ITEM_FORMAT_SHORT 0
|
||||
#define HID_ITEM_FORMAT_LONG 1
|
||||
|
||||
/*
|
||||
* Special tag indicating long items
|
||||
*/
|
||||
|
||||
#define HID_ITEM_TAG_LONG 15
|
||||
|
||||
/*
|
||||
* HID report descriptor item type (prefix bit 2,3)
|
||||
*/
|
||||
|
||||
#define HID_ITEM_TYPE_MAIN 0
|
||||
#define HID_ITEM_TYPE_GLOBAL 1
|
||||
#define HID_ITEM_TYPE_LOCAL 2
|
||||
#define HID_ITEM_TYPE_RESERVED 3
|
||||
|
||||
/*
|
||||
* HID report descriptor main item tags
|
||||
*/
|
||||
|
||||
#define HID_MAIN_ITEM_TAG_INPUT 8
|
||||
#define HID_MAIN_ITEM_TAG_OUTPUT 9
|
||||
#define HID_MAIN_ITEM_TAG_FEATURE 11
|
||||
#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
|
||||
#define HID_MAIN_ITEM_TAG_END_COLLECTION 12
|
||||
|
||||
/*
|
||||
* HID report descriptor main item contents
|
||||
*/
|
||||
|
||||
#define HID_MAIN_ITEM_CONSTANT 0x001
|
||||
#define HID_MAIN_ITEM_VARIABLE 0x002
|
||||
#define HID_MAIN_ITEM_RELATIVE 0x004
|
||||
#define HID_MAIN_ITEM_WRAP 0x008
|
||||
#define HID_MAIN_ITEM_NONLINEAR 0x010
|
||||
#define HID_MAIN_ITEM_NO_PREFERRED 0x020
|
||||
#define HID_MAIN_ITEM_NULL_STATE 0x040
|
||||
#define HID_MAIN_ITEM_VOLATILE 0x080
|
||||
#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
|
||||
|
||||
/*
|
||||
* HID report descriptor collection item types
|
||||
*/
|
||||
|
||||
#define HID_COLLECTION_PHYSICAL 0
|
||||
#define HID_COLLECTION_APPLICATION 1
|
||||
#define HID_COLLECTION_LOGICAL 2
|
||||
|
||||
/*
|
||||
* HID report descriptor global item tags
|
||||
*/
|
||||
|
||||
#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
|
||||
#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
|
||||
#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
|
||||
#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
|
||||
#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
|
||||
#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
|
||||
#define HID_GLOBAL_ITEM_TAG_UNIT 6
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
|
||||
#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
|
||||
#define HID_GLOBAL_ITEM_TAG_PUSH 10
|
||||
#define HID_GLOBAL_ITEM_TAG_POP 11
|
||||
|
||||
/*
|
||||
* HID report descriptor local item tags
|
||||
*/
|
||||
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE 0
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
|
||||
#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
|
||||
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
|
||||
#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
|
||||
#define HID_LOCAL_ITEM_TAG_DELIMITER 10
|
||||
|
||||
/*
|
||||
* HID usage tables
|
||||
*/
|
||||
|
||||
#define HID_USAGE_PAGE 0xffff0000
|
||||
|
||||
#define HID_UP_UNDEFINED 0x00000000
|
||||
#define HID_UP_GENDESK 0x00010000
|
||||
#define HID_UP_SIMULATION 0x00020000
|
||||
#define HID_UP_KEYBOARD 0x00070000
|
||||
#define HID_UP_LED 0x00080000
|
||||
#define HID_UP_BUTTON 0x00090000
|
||||
#define HID_UP_ORDINAL 0x000a0000
|
||||
#define HID_UP_CONSUMER 0x000c0000
|
||||
#define HID_UP_DIGITIZER 0x000d0000
|
||||
#define HID_UP_PID 0x000f0000
|
||||
#define HID_UP_HPVENDOR 0xff7f0000
|
||||
#define HID_UP_MSVENDOR 0xff000000
|
||||
#define HID_UP_CUSTOM 0x00ff0000
|
||||
#define HID_UP_LOGIVENDOR 0xffbc0000
|
||||
|
||||
#define HID_USAGE 0x0000ffff
|
||||
|
||||
#define HID_GD_POINTER 0x00010001
|
||||
#define HID_GD_MOUSE 0x00010002
|
||||
#define HID_GD_JOYSTICK 0x00010004
|
||||
#define HID_GD_GAMEPAD 0x00010005
|
||||
#define HID_GD_KEYBOARD 0x00010006
|
||||
#define HID_GD_KEYPAD 0x00010007
|
||||
#define HID_GD_MULTIAXIS 0x00010008
|
||||
#define HID_GD_X 0x00010030
|
||||
#define HID_GD_Y 0x00010031
|
||||
#define HID_GD_Z 0x00010032
|
||||
#define HID_GD_RX 0x00010033
|
||||
#define HID_GD_RY 0x00010034
|
||||
#define HID_GD_RZ 0x00010035
|
||||
#define HID_GD_SLIDER 0x00010036
|
||||
#define HID_GD_DIAL 0x00010037
|
||||
#define HID_GD_WHEEL 0x00010038
|
||||
#define HID_GD_HATSWITCH 0x00010039
|
||||
#define HID_GD_BUFFER 0x0001003a
|
||||
#define HID_GD_BYTECOUNT 0x0001003b
|
||||
#define HID_GD_MOTION 0x0001003c
|
||||
#define HID_GD_START 0x0001003d
|
||||
#define HID_GD_SELECT 0x0001003e
|
||||
#define HID_GD_VX 0x00010040
|
||||
#define HID_GD_VY 0x00010041
|
||||
#define HID_GD_VZ 0x00010042
|
||||
#define HID_GD_VBRX 0x00010043
|
||||
#define HID_GD_VBRY 0x00010044
|
||||
#define HID_GD_VBRZ 0x00010045
|
||||
#define HID_GD_VNO 0x00010046
|
||||
#define HID_GD_FEATURE 0x00010047
|
||||
#define HID_GD_UP 0x00010090
|
||||
#define HID_GD_DOWN 0x00010091
|
||||
#define HID_GD_RIGHT 0x00010092
|
||||
#define HID_GD_LEFT 0x00010093
|
||||
|
||||
/*
|
||||
* HID report types --- Ouch! HID spec says 1 2 3!
|
||||
*/
|
||||
|
||||
#define HID_INPUT_REPORT 0
|
||||
#define HID_OUTPUT_REPORT 1
|
||||
#define HID_FEATURE_REPORT 2
|
||||
|
||||
/*
|
||||
* HID device quirks.
|
||||
*/
|
||||
|
||||
#define HID_QUIRK_INVERT 0x00000001
|
||||
#define HID_QUIRK_NOTOUCH 0x00000002
|
||||
#define HID_QUIRK_IGNORE 0x00000004
|
||||
#define HID_QUIRK_NOGET 0x00000008
|
||||
#define HID_QUIRK_HIDDEV 0x00000010
|
||||
#define HID_QUIRK_BADPAD 0x00000020
|
||||
#define HID_QUIRK_MULTI_INPUT 0x00000040
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
|
||||
#define HID_QUIRK_MIGHTYMOUSE 0x00000400
|
||||
#define HID_QUIRK_CYMOTION 0x00000800
|
||||
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
|
||||
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
|
||||
#define HID_QUIRK_INVERT_HWHEEL 0x00004000
|
||||
#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000
|
||||
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000
|
||||
#define HID_QUIRK_IGNORE_MOUSE 0x00040000
|
||||
#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000
|
||||
#define HID_QUIRK_LOGITECH_S510_DESCRIPTOR 0x00100000
|
||||
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000
|
||||
|
||||
/*
|
||||
* This is the global environment of the parser. This information is
|
||||
* persistent for main-items. The global environment can be saved and
|
||||
* restored with PUSH/POP statements.
|
||||
*/
|
||||
|
||||
struct hid_global {
|
||||
unsigned usage_page;
|
||||
__s32 logical_minimum;
|
||||
__s32 logical_maximum;
|
||||
__s32 physical_minimum;
|
||||
__s32 physical_maximum;
|
||||
__s32 unit_exponent;
|
||||
unsigned unit;
|
||||
unsigned report_id;
|
||||
unsigned report_size;
|
||||
unsigned report_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the local environment. It is persistent up the next main-item.
|
||||
*/
|
||||
|
||||
#define HID_MAX_DESCRIPTOR_SIZE 4096
|
||||
#define HID_MAX_USAGES 8192
|
||||
#define HID_DEFAULT_NUM_COLLECTIONS 16
|
||||
|
||||
struct hid_local {
|
||||
unsigned usage[HID_MAX_USAGES]; /* usage array */
|
||||
unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
|
||||
unsigned usage_index;
|
||||
unsigned usage_minimum;
|
||||
unsigned delimiter_depth;
|
||||
unsigned delimiter_branch;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the collection stack. We climb up the stack to determine
|
||||
* application and function of each field.
|
||||
*/
|
||||
|
||||
struct hid_collection {
|
||||
unsigned type;
|
||||
unsigned usage;
|
||||
unsigned level;
|
||||
};
|
||||
|
||||
struct hid_usage {
|
||||
unsigned hid; /* hid usage code */
|
||||
unsigned collection_index; /* index into collection array */
|
||||
/* hidinput data */
|
||||
__u16 code; /* input driver code */
|
||||
__u8 type; /* input driver type */
|
||||
__s8 hat_min; /* hat switch fun */
|
||||
__s8 hat_max; /* ditto */
|
||||
__s8 hat_dir; /* ditto */
|
||||
};
|
||||
|
||||
struct hid_input;
|
||||
|
||||
struct hid_field {
|
||||
unsigned physical; /* physical usage for this field */
|
||||
unsigned logical; /* logical usage for this field */
|
||||
unsigned application; /* application usage for this field */
|
||||
struct hid_usage *usage; /* usage table for this function */
|
||||
unsigned maxusage; /* maximum usage index */
|
||||
unsigned flags; /* main-item flags (i.e. volatile,array,constant) */
|
||||
unsigned report_offset; /* bit offset in the report */
|
||||
unsigned report_size; /* size of this field in the report */
|
||||
unsigned report_count; /* number of this field in the report */
|
||||
unsigned report_type; /* (input,output,feature) */
|
||||
__s32 *value; /* last known value(s) */
|
||||
__s32 logical_minimum;
|
||||
__s32 logical_maximum;
|
||||
__s32 physical_minimum;
|
||||
__s32 physical_maximum;
|
||||
__s32 unit_exponent;
|
||||
unsigned unit;
|
||||
struct hid_report *report; /* associated report */
|
||||
unsigned index; /* index into report->field[] */
|
||||
/* hidinput data */
|
||||
struct hid_input *hidinput; /* associated input structure */
|
||||
__u16 dpad; /* dpad input code */
|
||||
};
|
||||
|
||||
#define HID_MAX_FIELDS 64
|
||||
|
||||
struct hid_report {
|
||||
struct list_head list;
|
||||
unsigned id; /* id of this report */
|
||||
unsigned type; /* report type */
|
||||
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
|
||||
unsigned maxfield; /* maximum valid field index */
|
||||
unsigned size; /* size of the report (bits) */
|
||||
struct hid_device *device; /* associated device */
|
||||
};
|
||||
|
||||
struct hid_report_enum {
|
||||
unsigned numbered;
|
||||
struct list_head report_list;
|
||||
struct hid_report *report_id_hash[256];
|
||||
};
|
||||
|
||||
#define HID_REPORT_TYPES 3
|
||||
|
||||
#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
|
||||
#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
|
||||
#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
|
||||
#define HID_OUTPUT_FIFO_SIZE 64
|
||||
|
||||
struct hid_control_fifo {
|
||||
unsigned char dir;
|
||||
struct hid_report *report;
|
||||
};
|
||||
|
||||
#define HID_CLAIMED_INPUT 1
|
||||
#define HID_CLAIMED_HIDDEV 2
|
||||
|
||||
#define HID_CTRL_RUNNING 1
|
||||
#define HID_OUT_RUNNING 2
|
||||
#define HID_IN_RUNNING 3
|
||||
#define HID_RESET_PENDING 4
|
||||
#define HID_SUSPENDED 5
|
||||
#define HID_CLEAR_HALT 6
|
||||
|
||||
struct hid_input {
|
||||
struct list_head list;
|
||||
struct hid_report *report;
|
||||
struct input_dev *input;
|
||||
};
|
||||
|
||||
struct hid_device { /* device report descriptor */
|
||||
__u8 *rdesc;
|
||||
unsigned rsize;
|
||||
struct hid_collection *collection; /* List of HID collections */
|
||||
unsigned collection_size; /* Number of allocated hid_collections */
|
||||
unsigned maxcollection; /* Number of parsed collections */
|
||||
unsigned maxapplication; /* Number of applications */
|
||||
unsigned short bus; /* BUS ID */
|
||||
unsigned short vendor; /* Vendor ID */
|
||||
unsigned short product; /* Product ID */
|
||||
unsigned version; /* HID version */
|
||||
unsigned country; /* HID country */
|
||||
struct hid_report_enum report_enum[HID_REPORT_TYPES];
|
||||
|
||||
struct device *dev; /* device */
|
||||
|
||||
unsigned claimed; /* Claimed by hidinput, hiddev? */
|
||||
unsigned quirks; /* Various quirks the device can pull on us */
|
||||
|
||||
struct list_head inputs; /* The list of inputs */
|
||||
void *hiddev; /* The hiddev structure */
|
||||
int minor; /* Hiddev minor number */
|
||||
|
||||
wait_queue_head_t wait; /* For sleeping */
|
||||
|
||||
int open; /* is the device open by anyone? */
|
||||
char name[128]; /* Device name */
|
||||
char phys[64]; /* Device physical location */
|
||||
char uniq[64]; /* Device unique identifier (serial #) */
|
||||
|
||||
void *driver_data;
|
||||
|
||||
/* device-specific function pointers */
|
||||
int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int);
|
||||
int (*hid_open) (struct hid_device *);
|
||||
void (*hid_close) (struct hid_device *);
|
||||
|
||||
/* hiddev event handler */
|
||||
void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
|
||||
struct hid_usage *, __s32);
|
||||
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
|
||||
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
|
||||
unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
|
||||
unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
|
||||
#endif
|
||||
};
|
||||
|
||||
#define HID_GLOBAL_STACK_SIZE 4
|
||||
#define HID_COLLECTION_STACK_SIZE 4
|
||||
|
||||
struct hid_parser {
|
||||
struct hid_global global;
|
||||
struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
|
||||
unsigned global_stack_ptr;
|
||||
struct hid_local local;
|
||||
unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
|
||||
unsigned collection_stack_ptr;
|
||||
struct hid_device *device;
|
||||
};
|
||||
|
||||
struct hid_class_descriptor {
|
||||
__u8 bDescriptorType;
|
||||
__u16 wDescriptorLength;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct hid_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u16 bcdHID;
|
||||
__u8 bCountryCode;
|
||||
__u8 bNumDescriptors;
|
||||
|
||||
struct hid_class_descriptor desc[1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
|
||||
/* We ignore a few input applications that are not widely used */
|
||||
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
|
||||
|
||||
/* HID core API */
|
||||
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
|
||||
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
|
||||
extern int hidinput_connect(struct hid_device *);
|
||||
extern void hidinput_disconnect(struct hid_device *);
|
||||
|
||||
int hid_set_field(struct hid_field *, unsigned, __s32);
|
||||
int hid_input_report(struct hid_device *, int type, u8 *, int, int);
|
||||
int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
|
||||
void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
|
||||
void hid_output_report(struct hid_report *report, __u8 *data);
|
||||
void hid_free_device(struct hid_device *device);
|
||||
struct hid_device *hid_parse_report(__u8 *start, unsigned size);
|
||||
|
||||
#ifdef CONFIG_HID_FF
|
||||
int hid_ff_init(struct hid_device *hid);
|
||||
|
||||
int hid_lgff_init(struct hid_device *hid);
|
||||
int hid_plff_init(struct hid_device *hid);
|
||||
int hid_tmff_init(struct hid_device *hid);
|
||||
int hid_zpff_init(struct hid_device *hid);
|
||||
#ifdef CONFIG_HID_PID
|
||||
int hid_pidff_init(struct hid_device *hid);
|
||||
#else
|
||||
static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
|
||||
#endif
|
||||
|
||||
#else
|
||||
static inline int hid_ff_init(struct hid_device *hid) { return -1; }
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
|
||||
__FILE__ , ## arg)
|
||||
#else
|
||||
#define dbg(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
|
||||
__FILE__ , ## arg)
|
||||
#endif
|
||||
|
||||
154
drivers/usb/uhci/hid.inc
Normal file
154
drivers/usb/uhci/hid.inc
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
struct hid_class_descriptor {
|
||||
u8_t bDescriptorType;
|
||||
u16_t wDescriptorLength;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct hid_descriptor {
|
||||
u8_t bLength;
|
||||
u8_t bDescriptorType;
|
||||
u16_t bcdHID;
|
||||
u8_t bCountryCode;
|
||||
u8_t bNumDescriptors;
|
||||
|
||||
struct hid_class_descriptor desc[1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d);
|
||||
|
||||
Bool init_hid(udev_t *dev)
|
||||
{
|
||||
interface_descr_t *interface;
|
||||
struct hid_descriptor *hds;
|
||||
struct hid_class_descriptor *hidclass;
|
||||
u8_t *dptr = (u8_t*)dev->conf;
|
||||
|
||||
int i=0, j=0;
|
||||
|
||||
dbgprintf( "init hid device\n");
|
||||
|
||||
dptr+= dev->conf->bLength;
|
||||
|
||||
// for(i = 0; i < dev->conf->bNumInterfaces; i++)
|
||||
// {
|
||||
interface = (interface_descr_t*)dptr;
|
||||
dptr+= interface->bLength;
|
||||
|
||||
dbgprintf("interface %d\n\n"
|
||||
"bLength %d\n"
|
||||
"bDescriptorType %d\n"
|
||||
"bInterfaceNumber %d\n"
|
||||
"bAlternateSetting %d\n"
|
||||
"bNumEndpoints %d\n"
|
||||
"bInterfaceClass %d\n"
|
||||
"bInterfaceSubClass %d\n"
|
||||
"bInterfaceProtocol %d\n"
|
||||
"iInterface %d\n\n",
|
||||
i+1,
|
||||
interface->bLength,
|
||||
interface->bDescriptorType,
|
||||
interface->bInterfaceNumber,
|
||||
interface->bAlternateSetting,
|
||||
interface->bNumEndpoints,
|
||||
interface->bInterfaceClass,
|
||||
interface->bInterfaceSubClass,
|
||||
interface->bInterfaceProtocol,
|
||||
interface->iInterface);
|
||||
|
||||
hds = (struct hid_descriptor*) dptr;
|
||||
|
||||
dbgprintf("hid descriptor\n\n"
|
||||
"bLength %d\n"
|
||||
"bDescriptorType %d\n"
|
||||
"bcdHID %x\n"
|
||||
"bCountryCode %d\n"
|
||||
"bNumDescriptors %d\n",
|
||||
hds->bLength,
|
||||
hds->bDescriptorType,
|
||||
hds->bcdHID,
|
||||
hds->bCountryCode,
|
||||
hds->bNumDescriptors);
|
||||
|
||||
for(j=0; j < hds->bNumDescriptors; j++)
|
||||
{
|
||||
dbgprintf("bDescriptorType %d\n"
|
||||
"wDescriptorLength %d\n",
|
||||
hds->desc[j].bDescriptorType,
|
||||
hds->desc[j].wDescriptorLength);
|
||||
};
|
||||
dptr+= hds->bLength;
|
||||
|
||||
endpoint_descr_t *ep;
|
||||
ep = (endpoint_descr_t*)dptr;
|
||||
|
||||
dbgprintf("\nendpoint\n\n"
|
||||
"bLength %d\n"
|
||||
"bDescriptorType %d\n"
|
||||
"bEndpointAddress %d\n"
|
||||
"bmAttributes %d\n"
|
||||
"wMaxPacketSize %d\n"
|
||||
"bInterval %d\n",
|
||||
ep->bLength, ep->bDescriptorType,
|
||||
ep->bEndpointAddress, ep->bmAttributes,
|
||||
ep->wMaxPacketSize, ep->bInterval);
|
||||
dptr+= ep->bLength;
|
||||
|
||||
if( interface->bInterfaceProtocol == 2)
|
||||
create_hid_mouse(dev, ep);
|
||||
// }
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
|
||||
Bool mouse_handler(udev_t *dev, struct tag_request *rq)
|
||||
{
|
||||
td_t *td;
|
||||
|
||||
td = rq->td_head;
|
||||
|
||||
if( (td->status &0x7FF)==rq->size-1)
|
||||
{
|
||||
struct boot_packet *pkt;
|
||||
pkt = (struct boot_packet *)rq->data;
|
||||
SetMouseData(pkt->buttons, pkt->x, -pkt->y, -pkt->z, 0);
|
||||
};
|
||||
td->status = 0x00800000 | dev->speed;
|
||||
td->token ^= DATA1;
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d)
|
||||
{
|
||||
request_t *rq;
|
||||
endp_t enp;
|
||||
|
||||
addr_t address;
|
||||
addr_t size;
|
||||
u32_t toggle;
|
||||
|
||||
void *packet;
|
||||
|
||||
td_t *td;
|
||||
qh_t *qh;
|
||||
|
||||
static u16_t __attribute__((aligned(16)))
|
||||
req_set_conf[4] = {0x0900,0x0001,0x0000,0x0000};
|
||||
|
||||
if( !ctrl_request(dev, req_set_conf, DOUT, 0, 0))
|
||||
return;
|
||||
|
||||
enp.address = en_d->bEndpointAddress;
|
||||
enp.size = en_d->wMaxPacketSize;
|
||||
enp.toggle = DATA0;
|
||||
|
||||
packet = malloc(enp.size);
|
||||
memset(packet, 0, enp.size);
|
||||
|
||||
rq = create_request(dev, &enp, DIN, packet, enp.size);
|
||||
rq->handler = &mouse_handler;
|
||||
|
||||
list_prepend(&rq->link, &rq_list);
|
||||
|
||||
dbgprintf("create_hid_mouse\n");
|
||||
}
|
||||
42
drivers/usb/uhci/makefile
Normal file
42
drivers/usb/uhci/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDRHD = -shared -T ld.x -s --file-alignment 32
|
||||
|
||||
INCLUDES = -I ../../include
|
||||
|
||||
HFILES:= ../../include/types.h \
|
||||
../../include/syscall.h \
|
||||
../../include/link.h \
|
||||
../../include/pci.h \
|
||||
usb.h
|
||||
|
||||
SRC_DEP:= pci.inc \
|
||||
detect.inc \
|
||||
hcd.inc \
|
||||
hid.inc
|
||||
|
||||
USB_SRC:= usb.c
|
||||
|
||||
USB_OBJ:= usb.obj
|
||||
|
||||
|
||||
USB = usb.dll
|
||||
|
||||
all: $(USB)
|
||||
|
||||
$(USB): $(USB_OBJ) $(SRC_DEP) $(HFILES) Makefile
|
||||
wlink name usb.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @usb.lk
|
||||
kpack.exe usb.dll usb.drv
|
||||
|
||||
usb.obj : usb.c $(SRC_DEP) $(HFILES) Makefile
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -o usb.obj usb.c
|
||||
|
||||
%.obj : %.c $(HFILES)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
%.obj: %.asm
|
||||
as -o $@ $<
|
||||
|
||||
|
||||
98
drivers/usb/uhci/pci.inc
Normal file
98
drivers/usb/uhci/pci.inc
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
|
||||
u32_t pciGetBaseSize(int bus, int devfn, int index,
|
||||
Bool destructive, Bool *min)
|
||||
{
|
||||
int offset;
|
||||
u32_t addr1;
|
||||
u32_t addr2;
|
||||
u32_t mask1;
|
||||
u32_t mask2;
|
||||
int bits = 0;
|
||||
|
||||
/*
|
||||
* silently ignore bogus index values. Valid values are 0-6. 0-5 are
|
||||
* the 6 base address registers, and 6 is the ROM base address register.
|
||||
*/
|
||||
if (index < 0 || index > 6)
|
||||
return 0;
|
||||
|
||||
if (min)
|
||||
*min = destructive;
|
||||
|
||||
/* Get the PCI offset */
|
||||
if (index == 6)
|
||||
offset = PCI_MAP_ROM_REG;
|
||||
else
|
||||
offset = PCI_MAP_REG_START + (index << 2);
|
||||
|
||||
addr1 = PciRead32(bus, devfn, offset);
|
||||
/*
|
||||
* Check if this is the second part of a 64 bit address.
|
||||
* XXX need to check how endianness affects 64 bit addresses.
|
||||
*/
|
||||
if (index > 0 && index < 6) {
|
||||
addr2 = PciRead32(bus, devfn, offset - 4);
|
||||
if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (destructive) {
|
||||
PciWrite32(bus, devfn, offset, 0xffffffff);
|
||||
mask1 = PciRead32(bus, devfn, offset);
|
||||
PciWrite32(bus, devfn, offset, addr1);
|
||||
} else {
|
||||
mask1 = addr1;
|
||||
}
|
||||
|
||||
/* Check if this is the first part of a 64 bit address. */
|
||||
if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
|
||||
{
|
||||
if (PCIGETMEMORY(mask1) == 0)
|
||||
{
|
||||
addr2 = PciRead32(bus, devfn, offset + 4);
|
||||
if (destructive)
|
||||
{
|
||||
PciWrite32(bus, devfn, offset + 4, 0xffffffff);
|
||||
mask2 = PciRead32(bus, devfn, offset + 4);
|
||||
PciWrite32(bus, devfn, offset + 4, addr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
mask2 = addr2;
|
||||
}
|
||||
if (mask2 == 0)
|
||||
return 0;
|
||||
bits = 32;
|
||||
while ((mask2 & 1) == 0)
|
||||
{
|
||||
bits++;
|
||||
mask2 >>= 1;
|
||||
}
|
||||
if (bits > 32)
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
if (index < 6)
|
||||
if (PCI_MAP_IS_MEM(mask1))
|
||||
mask1 = PCIGETMEMORY(mask1);
|
||||
else
|
||||
mask1 = PCIGETIO(mask1);
|
||||
else
|
||||
mask1 = PCIGETROM(mask1);
|
||||
if (mask1 == 0)
|
||||
return 0;
|
||||
bits = 0;
|
||||
while ((mask1 & 1) == 0) {
|
||||
bits++;
|
||||
mask1 >>= 1;
|
||||
}
|
||||
/* I/O maps can be no larger than 8 bits */
|
||||
|
||||
if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
|
||||
bits = 8;
|
||||
/* ROM maps can be no larger than 24 bits */
|
||||
if (index == 6 && bits > 24)
|
||||
bits = 24;
|
||||
return bits;
|
||||
}
|
||||
27
drivers/usb/uhci/usb.asm
Normal file
27
drivers/usb/uhci/usb.asm
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
use32
|
||||
|
||||
db 'MENUET01'
|
||||
dd 1
|
||||
dd start
|
||||
dd i_end
|
||||
dd mem
|
||||
dd mem
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
start:
|
||||
mov eax, 68
|
||||
mov ebx, 21
|
||||
mov ecx, sz_usb
|
||||
int 0x40
|
||||
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
sz_usb db '/rd/1/drivers/usb.drv',0
|
||||
|
||||
align 4
|
||||
i_end:
|
||||
rb 128
|
||||
mem:
|
||||
232
drivers/usb/uhci/usb.c
Normal file
232
drivers/usb/uhci/usb.c
Normal file
@@ -0,0 +1,232 @@
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "link.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include "syscall.h"
|
||||
#include "usb.h"
|
||||
|
||||
static Bool FindPciDevice();
|
||||
|
||||
int __stdcall srv_usb(ioctl_t *io);
|
||||
|
||||
Bool init_hc(hc_t *hc);
|
||||
|
||||
static slab_t qh_slab;
|
||||
static slab_t td_slab;
|
||||
|
||||
static link_t hc_list;
|
||||
static link_t newdev_list;
|
||||
static link_t rq_list;
|
||||
|
||||
u32_t __stdcall drvEntry(int action)
|
||||
{
|
||||
u32_t retval;
|
||||
hc_t *hc;
|
||||
udev_t *dev;
|
||||
|
||||
int i;
|
||||
|
||||
if(action != 1)
|
||||
return 0;
|
||||
|
||||
if(!dbg_open("/rd/1/drivers/usb.log"))
|
||||
{
|
||||
printf("Can't open /rd/1/drivers/usb.log\nExit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_initialize(&hc_list);
|
||||
list_initialize(&newdev_list);
|
||||
list_initialize(&rq_list);
|
||||
|
||||
if( !FindPciDevice() ) {
|
||||
dbgprintf("no uhci devices found\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
qh_slab.available = 256;
|
||||
qh_slab.start = KernelAlloc(4096);
|
||||
qh_slab.nextavail = (addr_t)qh_slab.start;
|
||||
qh_slab.dma = GetPgAddr(qh_slab.start);
|
||||
|
||||
qh_t *p;
|
||||
addr_t dma;
|
||||
|
||||
for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma;
|
||||
i < 256; i++, p++, dma+= sizeof(qh_t))
|
||||
{
|
||||
p->qlink = (addr_t)(p+1);
|
||||
p->qelem = 1;
|
||||
p->dma = dma;
|
||||
p->r1 = 0;
|
||||
};
|
||||
|
||||
td_slab.available = 128;
|
||||
td_slab.start = KernelAlloc(4096);
|
||||
td_slab.nextavail = (addr_t)td_slab.start;
|
||||
td_slab.dma = GetPgAddr(td_slab.start);
|
||||
|
||||
td_t *td;
|
||||
for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma;
|
||||
i < 128; i++, td++, dma+= sizeof(td_t))
|
||||
{
|
||||
td->link = (addr_t)(td+1);
|
||||
td->status = 0;
|
||||
td->token = 0;
|
||||
td->buffer = 0;
|
||||
td->dma = dma;
|
||||
};
|
||||
|
||||
|
||||
hc = (hc_t*)hc_list.next;
|
||||
|
||||
while( &hc->link != &hc_list)
|
||||
{
|
||||
init_hc(hc);
|
||||
hc = (hc_t*)hc->link.next;
|
||||
}
|
||||
|
||||
dbgprintf("\n");
|
||||
|
||||
dev = (udev_t*)newdev_list.next;
|
||||
while( &dev->link != &newdev_list)
|
||||
{
|
||||
udev_t *tmp = dev;
|
||||
dev = (udev_t*)dev->link.next;
|
||||
|
||||
if(tmp->id != 0)
|
||||
init_device(tmp);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
udev_t *dev;
|
||||
request_t *rq;
|
||||
|
||||
rq = (request_t*)rq_list.next;
|
||||
while( &rq->link != &rq_list)
|
||||
{
|
||||
qh_t *qh;
|
||||
td_t *td;
|
||||
|
||||
td = rq->td_head;
|
||||
dev = rq->dev;
|
||||
qh = dev->host->qh1;
|
||||
|
||||
qh->qelem = td->dma;
|
||||
|
||||
__asm__ __volatile__ ("":::"memory");
|
||||
rq = (request_t*)rq->link.next;
|
||||
};
|
||||
|
||||
delay(10/10);
|
||||
|
||||
rq = (request_t*)rq_list.next;
|
||||
while( &rq->link != &rq_list)
|
||||
{
|
||||
request_t *tmp;
|
||||
td_t *td;
|
||||
|
||||
tmp = rq;
|
||||
rq = (request_t*)rq->link.next;
|
||||
|
||||
td = tmp->td_head;
|
||||
|
||||
if( td->status & TD_CTRL_ACTIVE)
|
||||
continue;
|
||||
|
||||
tmp->handler(tmp->dev, tmp);
|
||||
};
|
||||
};
|
||||
|
||||
retval = RegService("USB", srv_usb);
|
||||
dbgprintf("reg service USB as: %x\n", retval);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
#define API_VERSION 0x01000100
|
||||
|
||||
#define SRV_GETVERSION 0
|
||||
|
||||
|
||||
int __stdcall srv_usb(ioctl_t *io)
|
||||
{
|
||||
u32_t *inp;
|
||||
u32_t *outp;
|
||||
|
||||
inp = io->input;
|
||||
outp = io->output;
|
||||
|
||||
switch(io->io_code)
|
||||
{
|
||||
case SRV_GETVERSION:
|
||||
if(io->out_size==4)
|
||||
{
|
||||
*outp = API_VERSION;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return ERR_PARAM;
|
||||
};
|
||||
return ERR_PARAM;
|
||||
}
|
||||
|
||||
|
||||
static qh_t* alloc_qh()
|
||||
{
|
||||
if( qh_slab.available )
|
||||
{
|
||||
qh_t *qh;
|
||||
|
||||
qh_slab.available--;
|
||||
qh = (qh_t*)qh_slab.nextavail;
|
||||
qh_slab.nextavail = qh->qlink;
|
||||
return qh;
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static void free_qh(qh_t *qh)
|
||||
{
|
||||
qh->qlink = qh_slab.nextavail;
|
||||
qh_slab.nextavail = (addr_t)qh;
|
||||
qh_slab.available++;
|
||||
};
|
||||
|
||||
static td_t* alloc_td()
|
||||
{
|
||||
if( td_slab.available )
|
||||
{
|
||||
td_t *td;
|
||||
|
||||
td_slab.available--;
|
||||
td = (td_t*)td_slab.nextavail;
|
||||
td_slab.nextavail = td->link;
|
||||
return td;
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
static void free_td(td_t *td)
|
||||
{
|
||||
td->link = td_slab.nextavail;
|
||||
td_slab.nextavail = (addr_t)td;
|
||||
td_slab.available++;
|
||||
};
|
||||
|
||||
#include "pci.inc"
|
||||
#include "detect.inc"
|
||||
#include "hcd.inc"
|
||||
#include "hid.inc"
|
||||
247
drivers/usb/uhci/usb.h
Normal file
247
drivers/usb/uhci/usb.h
Normal file
@@ -0,0 +1,247 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
int available; /**< Count of available items in this slab. */
|
||||
void *start; /**< Start address of first item. */
|
||||
addr_t nextavail; /**< The index of next available item. */
|
||||
addr_t dma;
|
||||
} slab_t;
|
||||
|
||||
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PHYSICAL 5
|
||||
#define USB_CLASS_STILL_IMAGE 6
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_CDC_DATA 0x0a
|
||||
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
|
||||
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
|
||||
#define USB_CLASS_VIDEO 0x0e
|
||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
||||
#define USB_CLASS_MISC 0xef
|
||||
#define USB_CLASS_APP_SPEC 0xfe
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
addr_t qlink;
|
||||
addr_t qelem;
|
||||
|
||||
addr_t dma;
|
||||
u32_t r1;
|
||||
|
||||
}qh_t __attribute__((aligned(16)));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t link;
|
||||
|
||||
addr_t iobase;
|
||||
|
||||
u32_t *frame_base;
|
||||
count_t frame_number;
|
||||
addr_t frame_dma;
|
||||
|
||||
qh_t *qh1;
|
||||
|
||||
u32_t *data;
|
||||
addr_t data_dma;
|
||||
|
||||
u32_t port_map;
|
||||
|
||||
int numports;
|
||||
|
||||
u32_t pciId;
|
||||
PCITAG PciTag;
|
||||
addr_t ioBase[6];
|
||||
addr_t memBase[6];
|
||||
size_t memSize[6];
|
||||
u32_t memType[6];
|
||||
}hc_t;
|
||||
|
||||
typedef struct tag_td
|
||||
{
|
||||
/* Hardware fields */
|
||||
addr_t link;
|
||||
u32_t status;
|
||||
u32_t token;
|
||||
addr_t buffer;
|
||||
|
||||
/* Software fields */
|
||||
addr_t dma;
|
||||
|
||||
struct tag_td *bk;
|
||||
|
||||
// struct list_head list;
|
||||
|
||||
// int frame; /* for iso: what frame? */
|
||||
// struct list_head fl_list;
|
||||
|
||||
u32_t reserved[2];
|
||||
} td_t __attribute__((aligned(16)));
|
||||
|
||||
#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
|
||||
#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
|
||||
#define TD_CTRL_C_ERR_SHIFT 27
|
||||
#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
|
||||
#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
|
||||
#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
|
||||
#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
|
||||
#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
|
||||
#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
|
||||
#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
|
||||
#define TD_CTRL_NAK (1 << 19) /* NAK Received */
|
||||
#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
|
||||
#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
|
||||
|
||||
#define TD_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
|
||||
TD_CTRL_BABBLE | TD_CTRL_CRCTIMEO | \
|
||||
TD_CTRL_BITSTUFF)
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u8_t bLength;
|
||||
u8_t bDescriptorType;
|
||||
u16_t bcdUSB;
|
||||
|
||||
u8_t bDeviceClass;
|
||||
u8_t bDeviceSubClass;
|
||||
u8_t bDeviceProtocol;
|
||||
u8_t bMaxPacketSize0;
|
||||
|
||||
u16_t idVendor;
|
||||
u16_t idProduct;
|
||||
u16_t bcdDevice;
|
||||
|
||||
u8_t iManufacturer;
|
||||
u8_t iProduct;
|
||||
u8_t iSerialNumber;
|
||||
u8_t bNumConfigurations;
|
||||
}dev_descr_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u8_t bLength;
|
||||
u8_t bDescriptorType;
|
||||
u16_t wTotalLength;
|
||||
u8_t bNumInterfaces;
|
||||
u8_t bConfigurationValue;
|
||||
u8_t iConfiguration;
|
||||
u8_t bmAttributes;
|
||||
u8_t bMaxPower;
|
||||
}conf_descr_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u8_t bLength;
|
||||
u8_t bDescriptorType;
|
||||
u8_t bInterfaceNumber;
|
||||
u8_t bAlternateSetting;
|
||||
u8_t bNumEndpoints;
|
||||
u8_t bInterfaceClass;
|
||||
u8_t bInterfaceSubClass;
|
||||
u8_t bInterfaceProtocol;
|
||||
u8_t iInterface;
|
||||
}interface_descr_t ;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u8_t bLength;
|
||||
u8_t bDescriptorType;
|
||||
|
||||
u8_t bEndpointAddress;
|
||||
u8_t bmAttributes;
|
||||
u16_t wMaxPacketSize;
|
||||
u8_t bInterval;
|
||||
|
||||
/* NOTE: these two are _only_ in audio endpoints. */
|
||||
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
|
||||
u8_t bRefresh;
|
||||
u8_t bSynchAddress;
|
||||
}endpoint_descr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
addr_t address;
|
||||
addr_t size;
|
||||
u32_t toggle;
|
||||
|
||||
}endp_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
u8_t bRequestType;
|
||||
u8_t bRequest;
|
||||
u16_t wValue;
|
||||
u16_t wIndex;
|
||||
u16_t wLength;
|
||||
}ctrl_request_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t link;
|
||||
u32_t id;
|
||||
|
||||
hc_t *host;
|
||||
|
||||
u32_t speed;
|
||||
addr_t addr;
|
||||
|
||||
addr_t ep0_size;
|
||||
|
||||
endp_t enp;
|
||||
|
||||
u32_t status;
|
||||
int port;
|
||||
|
||||
dev_descr_t dev_descr;
|
||||
conf_descr_t *conf;
|
||||
}udev_t;
|
||||
|
||||
typedef struct tag_request
|
||||
{
|
||||
link_t link;
|
||||
td_t *td_head;
|
||||
td_t *td_tail;
|
||||
addr_t data;
|
||||
size_t size;
|
||||
udev_t *dev;
|
||||
u32_t type;
|
||||
Bool (*handler)(udev_t *dev, struct tag_request *rq);
|
||||
}request_t;
|
||||
|
||||
|
||||
#define DMA(val) GetPgAddr(val)|(((addr_t)(val))&0xFFF)
|
||||
|
||||
#define TOKEN( size, toggle, ep, addr, pid) \
|
||||
( (((size)-1)<<21)|(toggle)|(((ep)&0xF)<<15)|((addr)<<8)|(pid))
|
||||
|
||||
Bool ctrl_request(udev_t *dev, void *req, u32_t dir,
|
||||
void *data, size_t req_size);
|
||||
|
||||
|
||||
Bool set_address(udev_t *dev);
|
||||
|
||||
Bool init_device(udev_t *dev);
|
||||
|
||||
Bool init_hid(udev_t *dev);
|
||||
|
||||
struct boot_packet
|
||||
{
|
||||
u8_t buttons;
|
||||
i8_t x;
|
||||
i8_t y;
|
||||
i8_t z;
|
||||
}__attribute__ ((packed));
|
||||
|
||||
#define DOUT 0xE1
|
||||
#define DIN 0x69
|
||||
|
||||
#define DATA0 (0<<19)
|
||||
#define DATA1 (1<<19)
|
||||
|
||||
22
drivers/usb/uhci/usb.lk
Normal file
22
drivers/usb/uhci/usb.lk
Normal file
@@ -0,0 +1,22 @@
|
||||
IMP
|
||||
_KernelAlloc core.KernelAlloc,
|
||||
_KernelFree core.KernelFree,
|
||||
_UserAlloc core.UserAlloc,
|
||||
_UserFree core.UserFree,
|
||||
_MapIoMem core.MapIoMem,
|
||||
_GetPgAddr core.GetPgAddr,
|
||||
_PciApi core.PciApi,
|
||||
_PciRead8 core.PciRead8,
|
||||
_PciRead16 core.PciRead16,
|
||||
_PciRead32 core.PciRead32,
|
||||
_PciWrite16 core.PciWrite16,
|
||||
_PciWrite32 core.PciWrite32,
|
||||
_RegService core.RegService,
|
||||
_SysMsgBoardStr core.SysMsgBoardStr,
|
||||
_Delay core.Delay,
|
||||
_SetMouseData core.SetMouseData
|
||||
|
||||
|
||||
FIL usb.obj,
|
||||
vsprintf.obj,
|
||||
icompute.obj
|
||||
602
drivers/video/agp/agp.c
Normal file
602
drivers/video/agp/agp.c
Normal file
@@ -0,0 +1,602 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "link.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include "agp.h"
|
||||
|
||||
#include "syscall.h"
|
||||
|
||||
|
||||
agp_t *bridge;
|
||||
|
||||
|
||||
int __stdcall srv_agp(ioctl_t *io);
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int action)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
int i;
|
||||
|
||||
if(action != 1)
|
||||
return 0;
|
||||
|
||||
if(!dbg_open("/rd/1/drivers/agp.log"))
|
||||
{
|
||||
printf("Can't open /rd/1/drivers/agp.log\nExit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( FindPciDevice() == 0)
|
||||
{
|
||||
dbgprintf("Device not found\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
// retval = RegService("AGP", srv_2d);
|
||||
// dbgprintf("reg service %s as: %x\n", "HDRAW", retval);
|
||||
|
||||
// return retval;
|
||||
};
|
||||
|
||||
|
||||
#include "pci.inc"
|
||||
#include "isoch.inc"
|
||||
|
||||
static void intel_8xx_tlbflush(void *mem)
|
||||
{
|
||||
u32_t temp;
|
||||
|
||||
temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL);
|
||||
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp & ~(1 << 7));
|
||||
temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL);
|
||||
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp | (1 << 7));
|
||||
}
|
||||
|
||||
|
||||
static aper_size_t intel_8xx_sizes[7] =
|
||||
{
|
||||
{ 256, 65536, 64, 0 },
|
||||
{ 128, 32768, 32, 32 },
|
||||
{ 64, 16384, 16, 48 },
|
||||
{ 32, 8192, 8, 56 },
|
||||
{ 16, 4096, 4, 60 },
|
||||
{ 8, 2048, 2, 62 },
|
||||
{ 4, 1024, 1, 63 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int intel_845_configure()
|
||||
{
|
||||
u32_t temp;
|
||||
u8_t temp2;
|
||||
aper_size_t *current_size;
|
||||
|
||||
current_size = bridge->current_size;
|
||||
|
||||
/* aperture size */
|
||||
pciWriteByte(bridge->PciTag, INTEL_APSIZE, current_size->size_value);
|
||||
|
||||
dbgprintf("INTEL_APSIZE %d\n", current_size->size_value );
|
||||
|
||||
if (bridge->apbase_config != 0)
|
||||
{
|
||||
pciWriteLong(bridge->PciTag, AGP_APBASE, bridge->apbase_config);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* address to map to */
|
||||
temp = pciReadLong(bridge->PciTag, AGP_APBASE);
|
||||
bridge->gart_addr = (temp & PCI_MAP_MEMORY_ADDRESS_MASK);
|
||||
bridge->apbase_config = temp;
|
||||
}
|
||||
|
||||
dbgprintf("AGP_APBASE %x\n", temp );
|
||||
|
||||
/* attbase - aperture base */
|
||||
pciWriteLong(bridge->PciTag, INTEL_ATTBASE, bridge->gatt_dma);
|
||||
|
||||
/* agpctrl */
|
||||
pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, 0x0000);
|
||||
|
||||
/* agpm */
|
||||
temp2 = pciReadByte(bridge->PciTag, INTEL_I845_AGPM);
|
||||
pciWriteByte(bridge->PciTag, INTEL_I845_AGPM, temp2 | (1 << 1));
|
||||
/* clear any possible error conditions */
|
||||
pciWriteWord(bridge->PciTag, INTEL_I845_ERRSTS, 0x001c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int agp_generic_create_gatt_table()
|
||||
{
|
||||
count_t pages;
|
||||
|
||||
pages = bridge->current_size->pages_count;
|
||||
|
||||
if( bridge->gatt_dma = AllocPages(pages))
|
||||
{
|
||||
if(bridge->gatt_table =
|
||||
(u32_t*)MapIoMem((void*)bridge->gatt_dma,
|
||||
pages<<12, PG_SW+PG_NOCACHE))
|
||||
{
|
||||
dbgprintf("gatt map %x at %x %d pages\n",bridge->gatt_dma ,
|
||||
bridge->gatt_table, pages);
|
||||
|
||||
/* AK: bogus, should encode addresses > 4GB */
|
||||
|
||||
u32_t volatile *table = bridge->gatt_table;
|
||||
|
||||
count_t count = bridge->current_size->num_entries;
|
||||
|
||||
while(count--) { /* FIXME memset */
|
||||
addr_t tmp;
|
||||
|
||||
*table = 0;
|
||||
table++;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
dbgprintf("unable to get memory for "
|
||||
"graphics translation table.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int __intel_8xx_fetch_size(u8_t temp)
|
||||
{
|
||||
int i;
|
||||
aper_size_t *values;
|
||||
|
||||
values = bridge->aperture_sizes;
|
||||
|
||||
values = intel_8xx_sizes;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
if (temp == values[i].size_value)
|
||||
{
|
||||
bridge->previous_size =
|
||||
bridge->current_size = (void *) (values + i);
|
||||
bridge->aperture_size_idx = i;
|
||||
return values[i].size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_8xx_fetch_size(void)
|
||||
{
|
||||
u8_t temp;
|
||||
|
||||
temp = pciReadByte(bridge->PciTag, INTEL_APSIZE);
|
||||
return __intel_8xx_fetch_size(temp);
|
||||
}
|
||||
|
||||
|
||||
int agp_bind_memory(addr_t agp_addr, addr_t dma_addr, size_t size)
|
||||
{
|
||||
int ret_val;
|
||||
count_t count;
|
||||
|
||||
// if (curr == NULL)
|
||||
// return -EINVAL;
|
||||
|
||||
// if (curr->is_bound == TRUE) {
|
||||
// printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
|
||||
// return -EINVAL;
|
||||
// }
|
||||
// if (curr->is_flushed == FALSE) {
|
||||
// curr->bridge->driver->cache_flush();
|
||||
// curr->is_flushed = TRUE;
|
||||
// }
|
||||
// ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
|
||||
|
||||
u32_t volatile *table = &bridge->gatt_table[agp_addr>>12];
|
||||
|
||||
count = size >> 12;
|
||||
|
||||
dma_addr |= 0x00000017;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
*table = dma_addr;
|
||||
table++;
|
||||
dma_addr+=4096;
|
||||
}
|
||||
|
||||
bridge->tlb_flush(NULL);
|
||||
|
||||
// if (ret_val != 0)
|
||||
// return ret_val;
|
||||
|
||||
// curr->is_bound = TRUE;
|
||||
// curr->pg_start = pg_start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_agp_version(agp_t *bridge)
|
||||
{
|
||||
u32_t ncapid;
|
||||
|
||||
/* Exit early if already set by errata workarounds. */
|
||||
if (bridge->major_version != 0)
|
||||
return;
|
||||
|
||||
ncapid = pciReadLong(bridge->PciTag, bridge->capndx);
|
||||
bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
|
||||
bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
|
||||
}
|
||||
|
||||
static void agp_v2_parse_one(u32_t *requested_mode, u32_t *bridge_agpstat, u32_t *vga_agpstat)
|
||||
{
|
||||
u32_t tmp;
|
||||
|
||||
if (*requested_mode & AGP2_RESERVED_MASK) {
|
||||
dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n",
|
||||
*requested_mode & AGP2_RESERVED_MASK, *requested_mode);
|
||||
*requested_mode &= ~AGP2_RESERVED_MASK;
|
||||
}
|
||||
|
||||
/* Check the speed bits make sense. Only one should be set. */
|
||||
tmp = *requested_mode & 7;
|
||||
switch (tmp) {
|
||||
case 0:
|
||||
dbgprintf("Setting to x1 mode.\n");
|
||||
*requested_mode |= AGPSTAT2_1X;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
*requested_mode &= ~(AGPSTAT2_1X); /* rate=2 */
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
*requested_mode &= ~(AGPSTAT2_1X|AGPSTAT2_2X); /* rate=4*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* disable SBA if it's not supported */
|
||||
if (!((*bridge_agpstat & AGPSTAT_SBA) && (*vga_agpstat & AGPSTAT_SBA) && (*requested_mode & AGPSTAT_SBA)))
|
||||
*bridge_agpstat &= ~AGPSTAT_SBA;
|
||||
|
||||
/* Set rate */
|
||||
if (!((*bridge_agpstat & AGPSTAT2_4X) && (*vga_agpstat & AGPSTAT2_4X) && (*requested_mode & AGPSTAT2_4X)))
|
||||
*bridge_agpstat &= ~AGPSTAT2_4X;
|
||||
|
||||
if (!((*bridge_agpstat & AGPSTAT2_2X) && (*vga_agpstat & AGPSTAT2_2X) && (*requested_mode & AGPSTAT2_2X)))
|
||||
*bridge_agpstat &= ~AGPSTAT2_2X;
|
||||
|
||||
if (!((*bridge_agpstat & AGPSTAT2_1X) && (*vga_agpstat & AGPSTAT2_1X) && (*requested_mode & AGPSTAT2_1X)))
|
||||
*bridge_agpstat &= ~AGPSTAT2_1X;
|
||||
|
||||
/* Now we know what mode it should be, clear out the unwanted bits. */
|
||||
if (*bridge_agpstat & AGPSTAT2_4X)
|
||||
*bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */
|
||||
|
||||
if (*bridge_agpstat & AGPSTAT2_2X)
|
||||
*bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */
|
||||
|
||||
if (*bridge_agpstat & AGPSTAT2_1X)
|
||||
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1X */
|
||||
|
||||
/* Apply any errata. */
|
||||
if (bridge->flags & AGP_ERRATA_FASTWRITES)
|
||||
*bridge_agpstat &= ~AGPSTAT_FW;
|
||||
|
||||
if (bridge->flags & AGP_ERRATA_SBA)
|
||||
*bridge_agpstat &= ~AGPSTAT_SBA;
|
||||
|
||||
if (bridge->flags & AGP_ERRATA_1X) {
|
||||
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X);
|
||||
*bridge_agpstat |= AGPSTAT2_1X;
|
||||
}
|
||||
|
||||
/* If we've dropped down to 1X, disable fast writes. */
|
||||
if (*bridge_agpstat & AGPSTAT2_1X)
|
||||
*bridge_agpstat &= ~AGPSTAT_FW;
|
||||
}
|
||||
|
||||
|
||||
static void agp_v3_parse_one(u32_t *requested_mode,
|
||||
u32_t *bridge_agpstat,
|
||||
u32_t *vga_agpstat)
|
||||
{
|
||||
u32_t origbridge = *bridge_agpstat, origvga = *vga_agpstat;
|
||||
u32_t tmp;
|
||||
|
||||
if (*requested_mode & AGP3_RESERVED_MASK)
|
||||
{
|
||||
dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n",
|
||||
*requested_mode & AGP3_RESERVED_MASK, *requested_mode);
|
||||
*requested_mode &= ~AGP3_RESERVED_MASK;
|
||||
}
|
||||
|
||||
/* Check the speed bits make sense. */
|
||||
tmp = *requested_mode & 7;
|
||||
if (tmp == 0) {
|
||||
dbgprintf("Setting to AGP3 x4 mode.\n");
|
||||
*requested_mode |= AGPSTAT3_4X;
|
||||
}
|
||||
if (tmp >= 3) {
|
||||
dbgprintf("Setting to AGP3 x8 mode.\n");
|
||||
*requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
|
||||
}
|
||||
|
||||
/* ARQSZ - Set the value to the maximum one.
|
||||
* Don't allow the mode register to override values. */
|
||||
*bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_ARQSZ) |
|
||||
max_t(u32_t,(*bridge_agpstat & AGPSTAT_ARQSZ),(*vga_agpstat & AGPSTAT_ARQSZ)));
|
||||
|
||||
/* Calibration cycle.
|
||||
* Don't allow the mode register to override values. */
|
||||
*bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_CAL_MASK) |
|
||||
min_t(u32_t,(*bridge_agpstat & AGPSTAT_CAL_MASK),(*vga_agpstat & AGPSTAT_CAL_MASK)));
|
||||
|
||||
/* SBA *must* be supported for AGP v3 */
|
||||
*bridge_agpstat |= AGPSTAT_SBA;
|
||||
|
||||
/*
|
||||
* Set speed.
|
||||
* Check for invalid speeds. This can happen when applications
|
||||
* written before the AGP 3.0 standard pass AGP2.x modes to AGP3 hardware
|
||||
*/
|
||||
if (*requested_mode & AGPSTAT_MODE_3_0) {
|
||||
/*
|
||||
* Caller hasn't a clue what it is doing. Bridge is in 3.0 mode,
|
||||
* have been passed a 3.0 mode, but with 2.x speed bits set.
|
||||
* AGP2.x 4x -> AGP3.0 4x.
|
||||
*/
|
||||
if (*requested_mode & AGPSTAT2_4X) {
|
||||
dbgprintf("broken AGP3 flags (%x). Fixed.\n", *requested_mode);
|
||||
*requested_mode &= ~AGPSTAT2_4X;
|
||||
*requested_mode |= AGPSTAT3_4X;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The caller doesn't know what they are doing. We are in 3.0 mode,
|
||||
* but have been passed an AGP 2.x mode.
|
||||
* Convert AGP 1x,2x,4x -> AGP 3.0 4x.
|
||||
*/
|
||||
dbgprintf("broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",*requested_mode);
|
||||
*requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X);
|
||||
*requested_mode |= AGPSTAT3_4X;
|
||||
}
|
||||
|
||||
if (*requested_mode & AGPSTAT3_8X) {
|
||||
if (!(*bridge_agpstat & AGPSTAT3_8X)) {
|
||||
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
|
||||
*bridge_agpstat |= AGPSTAT3_4X;
|
||||
dbgprintf("requested AGPx8 but bridge not capable.\n");
|
||||
return;
|
||||
}
|
||||
if (!(*vga_agpstat & AGPSTAT3_8X)) {
|
||||
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
|
||||
*bridge_agpstat |= AGPSTAT3_4X;
|
||||
dbgprintf("requested AGPx8 but graphic card not capable.\n");
|
||||
return;
|
||||
}
|
||||
/* All set, bridge & device can do AGP x8*/
|
||||
*bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
|
||||
goto done;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If we didn't specify AGPx8, we can only do x4.
|
||||
* If the hardware can't do x4, we're up shit creek, and never
|
||||
* should have got this far.
|
||||
*/
|
||||
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
|
||||
if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X))
|
||||
*bridge_agpstat |= AGPSTAT3_4X;
|
||||
else {
|
||||
dbgprintf("Badness. Don't know which AGP mode to set. "
|
||||
"[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n",
|
||||
origbridge, origvga, *bridge_agpstat, *vga_agpstat);
|
||||
if (!(*bridge_agpstat & AGPSTAT3_4X))
|
||||
dbgprintf("Bridge couldn't do AGP x4.\n");
|
||||
if (!(*vga_agpstat & AGPSTAT3_4X))
|
||||
dbgprintf("Graphic card couldn't do AGP x4.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
/* Apply any errata. */
|
||||
if (bridge->flags & AGP_ERRATA_FASTWRITES)
|
||||
*bridge_agpstat &= ~AGPSTAT_FW;
|
||||
|
||||
if (bridge->flags & AGP_ERRATA_SBA)
|
||||
*bridge_agpstat &= ~AGPSTAT_SBA;
|
||||
|
||||
if (bridge->flags & AGP_ERRATA_1X) {
|
||||
*bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X);
|
||||
*bridge_agpstat |= AGPSTAT2_1X;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u32_t agp_collect_device_status(agp_t *bridge, u32_t requested_mode,
|
||||
u32_t bridge_agpstat)
|
||||
{
|
||||
PCITAG vgaTag;
|
||||
u32_t vga_agpstat;
|
||||
int cap_ptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
vgaTag = pci_find_class(PCI_CLASS_DISPLAY_VGA);
|
||||
if (vgaTag == -1)
|
||||
{
|
||||
dbgprintf("Couldn't find an AGP VGA controller.\n");
|
||||
return 0;
|
||||
}
|
||||
cap_ptr = pci_find_capability(vgaTag, PCI_CAP_ID_AGP);
|
||||
if (cap_ptr)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, here we have a AGP device. Disable impossible
|
||||
* settings, and adjust the readqueue to the minimum.
|
||||
*/
|
||||
vga_agpstat = pciReadLong(vgaTag, cap_ptr+PCI_AGP_STATUS);
|
||||
|
||||
/* adjust RQ depth */
|
||||
bridge_agpstat = ((bridge_agpstat & ~AGPSTAT_RQ_DEPTH) |
|
||||
min_t(u32_t, (requested_mode & AGPSTAT_RQ_DEPTH),
|
||||
min_t(u32_t, (bridge_agpstat & AGPSTAT_RQ_DEPTH), (vga_agpstat & AGPSTAT_RQ_DEPTH))));
|
||||
|
||||
/* disable FW if it's not supported */
|
||||
if (!((bridge_agpstat & AGPSTAT_FW) &&
|
||||
(vga_agpstat & AGPSTAT_FW) &&
|
||||
(requested_mode & AGPSTAT_FW)))
|
||||
bridge_agpstat &= ~AGPSTAT_FW;
|
||||
|
||||
/* Check to see if we are operating in 3.0 mode */
|
||||
if (bridge->mode & AGPSTAT_MODE_3_0)
|
||||
agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
|
||||
else
|
||||
agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
|
||||
|
||||
return bridge_agpstat;
|
||||
}
|
||||
|
||||
|
||||
void agp_device_command(u32_t bridge_agpstat, int agp_v3)
|
||||
{
|
||||
PCITAG device = 0;
|
||||
int mode;
|
||||
|
||||
mode = bridge_agpstat & 0x7;
|
||||
if (agp_v3)
|
||||
mode *= 4;
|
||||
|
||||
for_each_pci_dev(device)
|
||||
{
|
||||
int agp = pci_find_capability(device, PCI_CAP_ID_AGP);
|
||||
if (!agp)
|
||||
continue;
|
||||
|
||||
dbgprintf("Putting AGP V%d device at into %dx mode\n",
|
||||
agp_v3 ? 3 : 2, mode);
|
||||
pciWriteLong(device, agp + PCI_AGP_COMMAND, bridge_agpstat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void agp_generic_enable(u32_t requested_mode)
|
||||
{
|
||||
u32_t bridge_agpstat, temp;
|
||||
|
||||
get_agp_version(bridge);
|
||||
|
||||
dbgprintf("Found an AGP %d.%d compliant device.\n",
|
||||
bridge->major_version, bridge->minor_version);
|
||||
|
||||
bridge_agpstat = pciReadLong(bridge->PciTag,
|
||||
bridge->capndx + PCI_AGP_STATUS);
|
||||
|
||||
bridge_agpstat = agp_collect_device_status(bridge, requested_mode, bridge_agpstat);
|
||||
if (bridge_agpstat == 0)
|
||||
/* Something bad happened. FIXME: Return error code? */
|
||||
return;
|
||||
|
||||
bridge_agpstat |= AGPSTAT_AGP_ENABLE;
|
||||
|
||||
/* Do AGP version specific frobbing. */
|
||||
if (bridge->major_version >= 3)
|
||||
{
|
||||
if (bridge->mode & AGPSTAT_MODE_3_0)
|
||||
{
|
||||
/* If we have 3.5, we can do the isoch stuff. */
|
||||
if (bridge->minor_version >= 5)
|
||||
agp_3_5_enable(bridge);
|
||||
agp_device_command(bridge_agpstat, TRUE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/
|
||||
bridge_agpstat &= ~(7<<10) ;
|
||||
temp = pciReadLong(bridge->PciTag, bridge->capndx+AGPCTRL);
|
||||
temp |= (1<<9);
|
||||
pciWriteLong(bridge->PciTag, bridge->capndx+AGPCTRL, temp);
|
||||
|
||||
dbgprintf("Device is in legacy mode,"
|
||||
" falling back to 2.x\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* AGP v<3 */
|
||||
agp_device_command(bridge_agpstat, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static agp_t intel_845_driver =
|
||||
{
|
||||
.aperture_sizes = intel_8xx_sizes,
|
||||
// .size_type = U8_APER_SIZE,
|
||||
// .num_aperture_sizes = 7,
|
||||
.configure = intel_845_configure,
|
||||
.fetch_size = intel_8xx_fetch_size,
|
||||
// .cleanup = intel_8xx_cleanup,
|
||||
.tlb_flush = intel_8xx_tlbflush,
|
||||
// .mask_memory = agp_generic_mask_memory,
|
||||
// .masks = intel_generic_masks,
|
||||
// .agp_enable = agp_generic_enable,
|
||||
// .cache_flush = global_cache_flush,
|
||||
.create_gatt_table = agp_generic_create_gatt_table,
|
||||
// .free_gatt_table = agp_generic_free_gatt_table,
|
||||
// .insert_memory = agp_generic_insert_memory,
|
||||
// .remove_memory = agp_generic_remove_memory,
|
||||
// .alloc_by_type = agp_generic_alloc_by_type,
|
||||
// .free_by_type = agp_generic_free_by_type,
|
||||
// .agp_alloc_page = agp_generic_alloc_page,
|
||||
// .agp_destroy_page = agp_generic_destroy_page,
|
||||
};
|
||||
|
||||
int init_bridge(PCITAG pciTag)
|
||||
{
|
||||
size_t size_value;
|
||||
|
||||
bridge = &intel_845_driver;
|
||||
|
||||
bridge->PciTag = pciTag;
|
||||
|
||||
bridge->capndx = pci_find_capability(pciTag, PCI_CAP_ID_AGP);
|
||||
|
||||
size_value = bridge->fetch_size();
|
||||
|
||||
if (size_value == 0) {
|
||||
dbgprintf("unable to determine aperture size.\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
dbgprintf("fetch size = %x\n", size_value);
|
||||
|
||||
if( bridge->create_gatt_table() )
|
||||
{
|
||||
bridge->configure();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include "detect.inc"
|
||||
147
drivers/video/agp/agp.h
Normal file
147
drivers/video/agp/agp.h
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
/* Chipset independant registers (from AGP Spec) */
|
||||
#define AGP_APBASE 0x10
|
||||
|
||||
#define AGPSTAT 0x4
|
||||
#define AGPCMD 0x8
|
||||
#define AGPNISTAT 0xc
|
||||
#define AGPCTRL 0x10
|
||||
#define AGPAPSIZE 0x14
|
||||
#define AGPNEPG 0x16
|
||||
#define AGPGARTLO 0x18
|
||||
#define AGPGARTHI 0x1c
|
||||
#define AGPNICMD 0x20
|
||||
|
||||
|
||||
#define AGP_MAJOR_VERSION_SHIFT (20)
|
||||
#define AGP_MINOR_VERSION_SHIFT (16)
|
||||
|
||||
#define AGPSTAT_RQ_DEPTH (0xff000000)
|
||||
#define AGPSTAT_RQ_DEPTH_SHIFT 24
|
||||
|
||||
#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10)
|
||||
#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13)
|
||||
#define AGPSTAT_ARQSZ_SHIFT 13
|
||||
|
||||
#define AGPSTAT_SBA (1<<9)
|
||||
#define AGPSTAT_AGP_ENABLE (1<<8)
|
||||
#define AGPSTAT_FW (1<<4)
|
||||
#define AGPSTAT_MODE_3_0 (1<<3)
|
||||
|
||||
#define AGPSTAT2_1X (1<<0)
|
||||
#define AGPSTAT2_2X (1<<1)
|
||||
#define AGPSTAT2_4X (1<<2)
|
||||
|
||||
#define AGPSTAT3_RSVD (1<<2)
|
||||
#define AGPSTAT3_8X (1<<1)
|
||||
#define AGPSTAT3_4X (1)
|
||||
|
||||
#define AGPCTRL_APERENB (1<<8)
|
||||
#define AGPCTRL_GTLBEN (1<<7)
|
||||
|
||||
#define AGP2_RESERVED_MASK 0x00fffcc8
|
||||
#define AGP3_RESERVED_MASK 0x00ff00c4
|
||||
|
||||
#define AGP_ERRATA_FASTWRITES 1<<0
|
||||
#define AGP_ERRATA_SBA 1<<1
|
||||
#define AGP_ERRATA_1X 1<<2
|
||||
|
||||
|
||||
|
||||
/* Intel registers */
|
||||
#define INTEL_APSIZE 0xb4
|
||||
#define INTEL_ATTBASE 0xb8
|
||||
#define INTEL_AGPCTRL 0xb0
|
||||
#define INTEL_NBXCFG 0x50
|
||||
#define INTEL_ERRSTS 0x91
|
||||
|
||||
/* Intel i845 registers */
|
||||
#define INTEL_I845_AGPM 0x51
|
||||
#define INTEL_I845_ERRSTS 0xc8
|
||||
|
||||
/* Chipset independant registers (from AGP Spec) */
|
||||
#define AGP_APBASE 0x10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
count_t num_entries;
|
||||
count_t pages_count;
|
||||
u32_t size_value;
|
||||
}aper_size_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PCITAG PciTag;
|
||||
|
||||
aper_size_t *aperture_sizes;
|
||||
aper_size_t *current_size;
|
||||
aper_size_t *previous_size;
|
||||
int aperture_size_idx;
|
||||
|
||||
u32_t volatile *gatt_table;
|
||||
addr_t gatt_dma;
|
||||
|
||||
addr_t apbase_config;
|
||||
addr_t gart_addr;
|
||||
|
||||
u32_t flags;
|
||||
u32_t mode;
|
||||
|
||||
int capndx;
|
||||
|
||||
char major_version;
|
||||
char minor_version;
|
||||
|
||||
// int num_aperture_sizes;
|
||||
// enum aper_size_type size_type;
|
||||
// int cant_use_aperture;
|
||||
// int needs_scratch_page;
|
||||
// struct gatt_mask *masks;
|
||||
int (*fetch_size)();
|
||||
int (*configure)();
|
||||
// void (*agp_enable)(struct agp_bridge_data *, u32);
|
||||
// void (*cleanup)(void);
|
||||
void (*tlb_flush)();
|
||||
// u32_t (*mask_memory)(struct agp_bridge_data *,u32_t, int);
|
||||
// void (*cache_flush)(void);
|
||||
int (*create_gatt_table)();
|
||||
// int (*free_gatt_table)(struct agp_bridge_data *);
|
||||
// int (*insert_memory)(struct agp_memory *, off_t, int);
|
||||
// int (*remove_memory)(struct agp_memory *, off_t, int);
|
||||
// struct agp_memory *(*alloc_by_type) (size_t, int);
|
||||
// void (*free_by_type)(struct agp_memory *);
|
||||
// void *(*agp_alloc_page)(struct agp_bridge_data *);
|
||||
// void (*agp_destroy_page)(void *);
|
||||
}agp_t;
|
||||
|
||||
/*
|
||||
* min()/max() macros that also do
|
||||
* strict type-checking.. See the
|
||||
* "unnecessary" pointer comparison.
|
||||
*/
|
||||
#define min(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x < _y ? _x : _y; })
|
||||
|
||||
#define max(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x > _y ? _x : _y; })
|
||||
|
||||
|
||||
#define min_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
|
||||
#define max_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
|
||||
|
||||
#define PCI_ANY_ID (~0)
|
||||
|
||||
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d))!=-1)
|
||||
|
||||
|
||||
|
||||
|
||||
27
drivers/video/agp/agp.lk
Normal file
27
drivers/video/agp/agp.lk
Normal file
@@ -0,0 +1,27 @@
|
||||
IMP
|
||||
_KernelAlloc core.KernelAlloc,
|
||||
_KernelFree core.KernelFree,
|
||||
_UserAlloc core.UserAlloc,
|
||||
_UserFree core.UserFree,
|
||||
_CommitPages core.CommitPages,
|
||||
_AllocPages core.AllocPages,
|
||||
_UnmapPages core.UnmapPages,
|
||||
_CreateObject core.CreateObject,
|
||||
_DestroyObject core.DestroyObject,
|
||||
_MapIoMem core.MapIoMem,
|
||||
_GetPgAddr core.GetPgAddr,
|
||||
_CreateRingBuffer core.CreateRingBuffer,
|
||||
_PciApi core.PciApi,
|
||||
_PciRead8 core.PciRead8,
|
||||
_PciRead16 core.PciRead16,
|
||||
_PciRead32 core.PciRead32,
|
||||
_PciWrite8 core.PciWrite8,
|
||||
_PciWrite16 core.PciWrite16,
|
||||
_PciWrite32 core.PciWrite32,
|
||||
_RegService core.RegService,
|
||||
_SysMsgBoardStr core.SysMsgBoardStr
|
||||
|
||||
|
||||
FIL agp.obj,
|
||||
vsprintf.obj,
|
||||
icompute.obj
|
||||
116
drivers/video/agp/detect.inc
Normal file
116
drivers/video/agp/detect.inc
Normal file
@@ -0,0 +1,116 @@
|
||||
|
||||
#define PCI_CLASS_BRIDGE_HOST 0x06
|
||||
|
||||
#define INTEL_82443LX_0 (0x7180<<16)|0x8086
|
||||
#define INTEL_82443BX_0 (0x7190<<16)|0x8086
|
||||
#define INTEL_82443GX_0 (0x71a0<<16)|0x8086
|
||||
#define INTEL_82810_MC1 (0x7120<<16)|0x8086
|
||||
#define INTEL_82810_MC3 (0x7122<<16)|0x8086
|
||||
#define INTEL_82810E_MC (0x7124<<16)|0x8086
|
||||
#define INTEL_82815_MC (0x1130<<16)|0x8086
|
||||
#define INTEL_82820_HB (0x2500<<16)|0x8086
|
||||
#define INTEL_82820_UP_HB (0x2501<<16)|0x8086
|
||||
#define INTEL_82830_HB (0x3575<<16)|0x8086
|
||||
#define INTEL_82840_HB (0x1a21<<16)|0x8086
|
||||
#define INTEL_82845_HB (0x1a30<<16)|0x8086
|
||||
#define INTEL_82845G_HB (0x2560<<16)|0x8086
|
||||
#define INTEL_82850_HB (0x2530<<16)|0x8086
|
||||
#define INTEL_82855PM_HB (0x3340<<16)|0x8086
|
||||
#define INTEL_82855GM_HB (0x3580<<16)|0x8086
|
||||
#define INTEL_82860_HB (0x2531<<16)|0x8086
|
||||
#define INTEL_82865_HB (0x2570<<16)|0x8086
|
||||
#define INTEL_82875_HB (0x2578<<16)|0x8086
|
||||
#define INTEL_7505_0 (0x2550<<16)|0x8086
|
||||
#define INTEL_7205_0 (0x255d<<16)|0x8086
|
||||
#define INTEL_82915G_HB (0x2580<<16)|0x8086
|
||||
#define INTEL_82915GM_HB (0x2590<<16)|0x8086
|
||||
#define INTEL_82945G_HB (0x2770<<16)|0x8086
|
||||
#define INTEL_82945GM_HB (0x27A0<<16)|0x8086
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
int driver;
|
||||
}pci_device_t;
|
||||
|
||||
|
||||
static pci_device_t agp_dev_table[] = {
|
||||
|
||||
// { INTEL_82443LX_0, 0 },
|
||||
// { INTEL_82443BX_0, 0 },
|
||||
// { INTEL_82443GX_0, 0 },
|
||||
// { INTEL_82810_MC1, 0 },
|
||||
// { INTEL_82810_MC3, 0 },
|
||||
// { INTEL_82810E_MC, 0 },
|
||||
// { INTEL_82815_MC, 0 },
|
||||
// { INTEL_82820_HB, 0 },
|
||||
// { INTEL_82820_UP_HB,0 },
|
||||
// { INTEL_82830_HB, 0 },
|
||||
// { INTEL_82840_HB, 0 },
|
||||
// { INTEL_82845_HB, 0 },
|
||||
// { INTEL_82845G_HB, 0 },
|
||||
// { INTEL_82850_HB, 0 },
|
||||
// { INTEL_82855PM_HB, 0 },
|
||||
// { INTEL_82855GM_HB, 0 },
|
||||
// { INTEL_82860_HB, 0 },
|
||||
{ INTEL_82865_HB, 0 },
|
||||
// { INTEL_82875_HB, 0 },
|
||||
// { INTEL_7505_0, 0 },
|
||||
// { INTEL_7205_0, 0 },
|
||||
// { INTEL_82915G_HB, 0 },
|
||||
// { INTEL_82915GM_HB, 0 },
|
||||
// { INTEL_82945G_HB, 0 },
|
||||
// { INTEL_82945GM_HB, 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
pci_device_t* agp_dev_match(u32_t dev, pci_device_t *list)
|
||||
{
|
||||
while(list->id)
|
||||
{
|
||||
if(dev == list->id)
|
||||
return list;
|
||||
list++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int FindPciDevice()
|
||||
{
|
||||
u32_t bus, last_bus;
|
||||
PCITAG tag;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return 0;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
u32_t pciId;
|
||||
u8_t devclass;
|
||||
pci_device_t *dev;
|
||||
|
||||
pciId = PciRead32(bus,devfn, 0);
|
||||
devclass = PciRead8(bus,devfn, 0x0B);
|
||||
|
||||
if( devclass != PCI_CLASS_BRIDGE_HOST)
|
||||
continue;
|
||||
|
||||
if( (dev = agp_dev_match(pciId, agp_dev_table))!=NULL)
|
||||
{
|
||||
dbgprintf("detect agp host %x\n",dev->id);
|
||||
|
||||
PCITAG PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
|
||||
return init_bridge(PciTag);
|
||||
};
|
||||
};
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
483
drivers/video/agp/isoch.inc
Normal file
483
drivers/video/agp/isoch.inc
Normal file
@@ -0,0 +1,483 @@
|
||||
|
||||
struct agp_3_5_dev
|
||||
{
|
||||
link_t link;
|
||||
int capndx;
|
||||
u32_t maxbw;
|
||||
PCITAG tag;
|
||||
};
|
||||
|
||||
static inline list_insert_tail(link_t *new, link_t *old)
|
||||
{
|
||||
new->prev = old;
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
old->next = new;
|
||||
}
|
||||
|
||||
static void agp_3_5_dev_list_insert(link_t *head, link_t *new)
|
||||
{
|
||||
struct agp_3_5_dev *cur, *n = (struct agp_3_5_dev*)new;
|
||||
link_t *pos = head->next;
|
||||
|
||||
while(pos != head){
|
||||
cur = (struct agp_3_5_dev*)pos;
|
||||
if(cur->maxbw > n->maxbw)
|
||||
break;
|
||||
}
|
||||
list_insert_tail(new, pos);
|
||||
}
|
||||
|
||||
static void agp_3_5_dev_list_sort(link_t *list, unsigned int ndevs)
|
||||
{
|
||||
struct agp_3_5_dev *cur;
|
||||
link_t *pos, *tmp, *start = list->next;
|
||||
u32_t nistat;
|
||||
|
||||
list_initialize(list);
|
||||
|
||||
for (pos = start; pos != list; )
|
||||
{
|
||||
PCITAG tag;
|
||||
|
||||
cur = (struct agp_3_5_dev*)pos;
|
||||
tag = cur->tag;
|
||||
|
||||
nistat = pciReadLong(tag, cur->capndx+AGPNISTAT);
|
||||
cur->maxbw = (nistat >> 16) & 0xff;
|
||||
|
||||
tmp = pos;
|
||||
pos = pos->next;
|
||||
agp_3_5_dev_list_insert(list, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize all isochronous transfer parameters for an AGP 3.0
|
||||
* node (i.e. a host bridge in combination with the adapters
|
||||
* lying behind it...)
|
||||
*/
|
||||
|
||||
static int agp_3_5_isochronous_node_enable(agp_t *bridge,
|
||||
link_t *dev_list, unsigned int ndevs)
|
||||
{
|
||||
/*
|
||||
* Convenience structure to make the calculations clearer
|
||||
* here. The field names come straight from the AGP 3.0 spec.
|
||||
*/
|
||||
struct isoch_data {
|
||||
u32_t maxbw;
|
||||
u32_t n;
|
||||
u32_t y;
|
||||
u32_t l;
|
||||
u32_t rq;
|
||||
struct agp_3_5_dev *dev;
|
||||
};
|
||||
|
||||
PCITAG td = bridge->PciTag;
|
||||
|
||||
// struct list_head *head = &dev_list->list, *pos;
|
||||
struct agp_3_5_dev *cur;
|
||||
struct isoch_data *master, target;
|
||||
unsigned int cdev = 0;
|
||||
u32_t mnistat, tnistat, tstatus, mcmd;
|
||||
u16_t tnicmd, mnicmd;
|
||||
u8_t mcapndx;
|
||||
u32_t tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async;
|
||||
u32_t step, rem, rem_isoch, rem_async;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* We'll work with an array of isoch_data's (one for each
|
||||
* device in dev_list) throughout this function.
|
||||
*/
|
||||
if ((master = malloc(ndevs * sizeof(*master))) == NULL) {
|
||||
ret = -1;
|
||||
goto get_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort the device list by maxbw. We need to do this because the
|
||||
* spec suggests that the devices with the smallest requirements
|
||||
* have their resources allocated first, with all remaining resources
|
||||
* falling to the device with the largest requirement.
|
||||
*
|
||||
* We don't exactly do this, we divide target resources by ndevs
|
||||
* and split them amongst the AGP 3.0 devices. The remainder of such
|
||||
* division operations are dropped on the last device, sort of like
|
||||
* the spec mentions it should be done.
|
||||
*
|
||||
* We can't do this sort when we initially construct the dev_list
|
||||
* because we don't know until this function whether isochronous
|
||||
* transfers are enabled and consequently whether maxbw will mean
|
||||
* anything.
|
||||
*/
|
||||
agp_3_5_dev_list_sort(dev_list, ndevs);
|
||||
|
||||
tnistat = pciReadLong(td, bridge->capndx+AGPNISTAT);
|
||||
tstatus = pciReadLong(td, bridge->capndx+AGPSTAT);
|
||||
|
||||
/* Extract power-on defaults from the target */
|
||||
target.maxbw = (tnistat >> 16) & 0xff;
|
||||
target.n = (tnistat >> 8) & 0xff;
|
||||
target.y = (tnistat >> 6) & 0x3;
|
||||
target.l = (tnistat >> 3) & 0x7;
|
||||
target.rq = (tstatus >> 24) & 0xff;
|
||||
|
||||
y_max = target.y;
|
||||
|
||||
/*
|
||||
* Extract power-on defaults for each device in dev_list. Along
|
||||
* the way, calculate the total isochronous bandwidth required
|
||||
* by these devices and the largest requested payload size.
|
||||
*/
|
||||
|
||||
link_t *pos;
|
||||
|
||||
for (pos = dev_list->next; pos != dev_list; pos = pos->next )
|
||||
{
|
||||
PCITAG dev;
|
||||
|
||||
cur = (struct agp_3_5_dev*)pos;
|
||||
dev = cur->tag;
|
||||
|
||||
mcapndx = cur->capndx;
|
||||
|
||||
mnistat = pciReadLong(dev, cur->capndx+AGPNISTAT);
|
||||
|
||||
master[cdev].maxbw = (mnistat >> 16) & 0xff;
|
||||
master[cdev].n = (mnistat >> 8) & 0xff;
|
||||
master[cdev].y = (mnistat >> 6) & 0x3;
|
||||
master[cdev].dev = cur;
|
||||
|
||||
tot_bw += master[cdev].maxbw;
|
||||
y_max = max(y_max, master[cdev].y);
|
||||
|
||||
cdev++;
|
||||
}
|
||||
|
||||
/* Check if this configuration has any chance of working */
|
||||
if (tot_bw > target.maxbw) {
|
||||
dbgprintf("isochronous bandwidth required "
|
||||
"by AGP 3.0 devices exceeds that which is supported by "
|
||||
"the AGP 3.0 bridge!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
target.y = y_max;
|
||||
|
||||
/*
|
||||
* Write the calculated payload size into the target's NICMD
|
||||
* register. Doing this directly effects the ISOCH_N value
|
||||
* in the target's NISTAT register, so we need to do this now
|
||||
* to get an accurate value for ISOCH_N later.
|
||||
*/
|
||||
tnicmd = pciReadWord(td, bridge->capndx+AGPNICMD);
|
||||
tnicmd &= ~(0x3 << 6);
|
||||
tnicmd |= target.y << 6;
|
||||
pciWriteWord(td, bridge->capndx+AGPNICMD, tnicmd);
|
||||
|
||||
/* Reread the target's ISOCH_N */
|
||||
tnistat = pciReadLong(td, bridge->capndx+AGPNISTAT);
|
||||
target.n = (tnistat >> 8) & 0xff;
|
||||
|
||||
/* Calculate the minimum ISOCH_N needed by each master */
|
||||
for (cdev=0; cdev<ndevs; cdev++) {
|
||||
master[cdev].y = target.y;
|
||||
master[cdev].n = master[cdev].maxbw / (master[cdev].y + 1);
|
||||
|
||||
tot_n += master[cdev].n;
|
||||
}
|
||||
|
||||
/* Exit if the minimal ISOCH_N allocation among the masters is more
|
||||
* than the target can handle. */
|
||||
if (tot_n > target.n) {
|
||||
dbgprintf("number of isochronous "
|
||||
"transactions per period required by AGP 3.0 devices "
|
||||
"exceeds that which is supported by the AGP 3.0 "
|
||||
"bridge!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
/* Calculate left over ISOCH_N capability in the target. We'll give
|
||||
* this to the hungriest device (as per the spec) */
|
||||
rem = target.n - tot_n;
|
||||
|
||||
/*
|
||||
* Calculate the minimum isochronous RQ depth needed by each master.
|
||||
* Along the way, distribute the extra ISOCH_N capability calculated
|
||||
* above.
|
||||
*/
|
||||
for (cdev=0; cdev<ndevs; cdev++) {
|
||||
/*
|
||||
* This is a little subtle. If ISOCH_Y > 64B, then ISOCH_Y
|
||||
* byte isochronous writes will be broken into 64B pieces.
|
||||
* This means we need to budget more RQ depth to account for
|
||||
* these kind of writes (each isochronous write is actually
|
||||
* many writes on the AGP bus).
|
||||
*/
|
||||
master[cdev].rq = master[cdev].n;
|
||||
if(master[cdev].y > 0x1)
|
||||
master[cdev].rq *= (1 << (master[cdev].y - 1));
|
||||
|
||||
tot_rq += master[cdev].rq;
|
||||
}
|
||||
master[ndevs-1].n += rem;
|
||||
|
||||
/* Figure the number of isochronous and asynchronous RQ slots the
|
||||
* target is providing. */
|
||||
rq_isoch = (target.y > 0x1) ? target.n * (1 << (target.y - 1)) : target.n;
|
||||
rq_async = target.rq - rq_isoch;
|
||||
|
||||
/* Exit if the minimal RQ needs of the masters exceeds what the target
|
||||
* can provide. */
|
||||
if (tot_rq > rq_isoch) {
|
||||
dbgprintf("number of request queue slots "
|
||||
"required by the isochronous bandwidth requested by "
|
||||
"AGP 3.0 devices exceeds the number provided by the "
|
||||
"AGP 3.0 bridge!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
/* Calculate asynchronous RQ capability in the target (per master) as
|
||||
* well as the total number of leftover isochronous RQ slots. */
|
||||
step = rq_async / ndevs;
|
||||
rem_async = step + (rq_async % ndevs);
|
||||
rem_isoch = rq_isoch - tot_rq;
|
||||
|
||||
/* Distribute the extra RQ slots calculated above and write our
|
||||
* isochronous settings out to the actual devices. */
|
||||
for (cdev=0; cdev<ndevs; cdev++)
|
||||
{
|
||||
PCITAG dev;
|
||||
|
||||
cur = master[cdev].dev;
|
||||
dev = cur->tag;
|
||||
|
||||
mcapndx = cur->capndx;
|
||||
|
||||
master[cdev].rq += (cdev == ndevs - 1)
|
||||
? (rem_async + rem_isoch) : step;
|
||||
|
||||
mnicmd = pciReadWord(dev, cur->capndx+AGPNICMD);
|
||||
mcmd = pciReadLong(dev, cur->capndx+AGPCMD);
|
||||
|
||||
mnicmd &= ~(0xff << 8);
|
||||
mnicmd &= ~(0x3 << 6);
|
||||
mcmd &= ~(0xff << 24);
|
||||
|
||||
mnicmd |= master[cdev].n << 8;
|
||||
mnicmd |= master[cdev].y << 6;
|
||||
mcmd |= master[cdev].rq << 24;
|
||||
|
||||
pciWriteLong(dev, cur->capndx+AGPCMD, mcmd);
|
||||
pciWriteWord(dev, cur->capndx+AGPNICMD, mnicmd);
|
||||
}
|
||||
|
||||
free_and_exit:
|
||||
free(master);
|
||||
|
||||
get_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function basically allocates request queue slots among the
|
||||
* AGP 3.0 systems in nonisochronous nodes. The algorithm is
|
||||
* pretty stupid, divide the total number of RQ slots provided by the
|
||||
* target by ndevs. Distribute this many slots to each AGP 3.0 device,
|
||||
* giving any left over slots to the last device in dev_list.
|
||||
*/
|
||||
static void agp_3_5_nonisochronous_node_enable(agp_t *bridge,
|
||||
link_t *dev_list, unsigned int ndevs)
|
||||
{
|
||||
struct agp_3_5_dev *cur;
|
||||
u32_t tstatus, mcmd;
|
||||
u32_t trq, mrq, rem;
|
||||
unsigned int cdev = 0;
|
||||
|
||||
tstatus = pciReadLong(bridge->PciTag, bridge->capndx+AGPSTAT);
|
||||
|
||||
trq = (tstatus >> 24) & 0xff;
|
||||
mrq = trq / ndevs;
|
||||
|
||||
rem = mrq + (trq % ndevs);
|
||||
|
||||
link_t *pos;
|
||||
|
||||
for (pos = dev_list->next; cdev<ndevs; cdev++, pos=pos->next) {
|
||||
cur = (struct agp_3_5_dev*)pos;
|
||||
|
||||
mcmd = pciReadLong(cur->tag, cur->capndx+AGPCMD);
|
||||
mcmd &= ~(0xff << 24);
|
||||
mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24;
|
||||
pciWriteLong(cur->tag, cur->capndx+AGPCMD, mcmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Fully configure and enable an AGP 3.0 host bridge and all the devices
|
||||
* lying behind it.
|
||||
*/
|
||||
int agp_3_5_enable(agp_t *bridge)
|
||||
{
|
||||
u8_t mcapndx;
|
||||
u32_t isoch, arqsz;
|
||||
u32_t tstatus, mstatus, ncapid;
|
||||
u32_t mmajor;
|
||||
u16_t mpstat;
|
||||
|
||||
link_t dev_list;
|
||||
|
||||
struct agp_3_5_dev *cur, *pos;
|
||||
|
||||
unsigned int ndevs = 0;
|
||||
PCITAG dev = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Extract some power-on defaults from the target */
|
||||
tstatus = pciReadLong(bridge->PciTag, bridge->capndx+AGPSTAT);
|
||||
isoch = (tstatus >> 17) & 0x1;
|
||||
if (isoch == 0) /* isoch xfers not available, bail out. */
|
||||
return -1;
|
||||
|
||||
arqsz = (tstatus >> 13) & 0x7;
|
||||
|
||||
list_initialize(&dev_list);
|
||||
|
||||
/* Find all AGP devices, and add them to dev_list. */
|
||||
for_each_pci_dev(dev)
|
||||
{
|
||||
u16_t devclass;
|
||||
|
||||
mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
|
||||
if (mcapndx == 0)
|
||||
continue;
|
||||
|
||||
devclass = pciReadWord(dev, 0x0A);
|
||||
|
||||
switch (devclass & 0xff00)
|
||||
{
|
||||
case 0x0600: /* Bridge */
|
||||
/* Skip bridges. We should call this function for each one. */
|
||||
continue;
|
||||
|
||||
case 0x0001: /* Unclassified device */
|
||||
/* Don't know what this is, but log it for investigation. */
|
||||
if (mcapndx != 0) {
|
||||
dbgprintf("Wacky, found unclassified AGP device.\n");
|
||||
}
|
||||
continue;
|
||||
|
||||
case 0x0300: /* Display controller */
|
||||
case 0x0400: /* Multimedia controller */
|
||||
if((cur = malloc(sizeof(*cur))) == NULL)
|
||||
{
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
cur->tag = dev;
|
||||
list_prepend(&cur->link, &dev_list);
|
||||
ndevs++;
|
||||
continue;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Take an initial pass through the devices lying behind our host
|
||||
* bridge. Make sure each one is actually an AGP 3.0 device, otherwise
|
||||
* exit with an error message. Along the way store the AGP 3.0
|
||||
* cap_ptr for each device
|
||||
*/
|
||||
|
||||
cur = (struct agp_3_5_dev*)dev_list.next;
|
||||
|
||||
while(&cur->link != &dev_list)
|
||||
{
|
||||
dev = cur->tag;
|
||||
|
||||
mpstat = pciReadWord(dev, PCI_STATUS);
|
||||
if ((mpstat & PCI_STATUS_CAP_LIST) == 0)
|
||||
continue;
|
||||
|
||||
mcapndx = pciReadByte(dev, PCI_CAPABILITY_LIST);
|
||||
if (mcapndx != 0) {
|
||||
do {
|
||||
ncapid = pciReadLong(dev, mcapndx);
|
||||
if ((ncapid & 0xff) != 2)
|
||||
mcapndx = (ncapid >> 8) & 0xff;
|
||||
}
|
||||
while (((ncapid & 0xff) != 2) && (mcapndx != 0));
|
||||
}
|
||||
|
||||
if (mcapndx == 0) {
|
||||
dbgprintf("woah! Non-AGP device "
|
||||
"found on the secondary bus of an AGP 3.5 bridge!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
|
||||
if (mmajor < 3) {
|
||||
dbgprintf("woah! AGP 2.0 device "
|
||||
"found on the secondary bus of an AGP 3.5 "
|
||||
"bridge operating with AGP 3.0 electricals!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
cur->capndx = mcapndx;
|
||||
|
||||
mstatus = pciReadLong(dev, cur->capndx+AGPSTAT);
|
||||
|
||||
if (((mstatus >> 3) & 0x1) == 0) {
|
||||
dbgprintf("woah! AGP 3.x device "
|
||||
"not operating in AGP 3.x mode found on the "
|
||||
"secondary bus of an AGP 3.5 bridge operating "
|
||||
"with AGP 3.0 electricals!\n");
|
||||
ret = -1;
|
||||
goto free_and_exit;
|
||||
}
|
||||
cur = (struct agp_3_5_dev*)cur->link.next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call functions to divide target resources amongst the AGP 3.0
|
||||
* masters. This process is dramatically different depending on
|
||||
* whether isochronous transfers are supported.
|
||||
*/
|
||||
if (isoch) {
|
||||
ret = agp_3_5_isochronous_node_enable(bridge, &dev_list, ndevs);
|
||||
if (ret) {
|
||||
dbgprintf("Something bad happened setting "
|
||||
"up isochronous xfers. Falling back to "
|
||||
"non-isochronous xfer mode.\n");
|
||||
} else {
|
||||
goto free_and_exit;
|
||||
}
|
||||
}
|
||||
agp_3_5_nonisochronous_node_enable(bridge, &dev_list, ndevs);
|
||||
|
||||
free_and_exit:
|
||||
/* Be sure to free the dev_list */
|
||||
for (pos = (struct agp_3_5_dev*)dev_list.next; &pos->link != &dev_list; )
|
||||
{
|
||||
cur = pos;
|
||||
|
||||
pos = (struct agp_3_5_dev*)pos->link.next;
|
||||
free(cur);
|
||||
}
|
||||
|
||||
get_out:
|
||||
return ret;
|
||||
}
|
||||
60
drivers/video/agp/link.h
Normal file
60
drivers/video/agp/link.h
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
typedef struct link
|
||||
{
|
||||
struct link *prev;
|
||||
struct link *next;
|
||||
}link_t;
|
||||
|
||||
#define LIST_INITIALIZE(name) \
|
||||
link_t name = { .prev = &name, .next = &name }
|
||||
|
||||
#define list_get_instance(link, type, member) \
|
||||
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
|
||||
|
||||
static inline void link_initialize(link_t *link)
|
||||
{
|
||||
link->prev = NULL;
|
||||
link->next = NULL;
|
||||
}
|
||||
|
||||
static inline void list_initialize(link_t *head)
|
||||
{
|
||||
head->prev = head;
|
||||
head->next = head;
|
||||
}
|
||||
|
||||
static inline void list_append(link_t *link, link_t *head)
|
||||
{
|
||||
link->prev = head->prev;
|
||||
link->next = head;
|
||||
head->prev->next = link;
|
||||
head->prev = link;
|
||||
}
|
||||
|
||||
static inline void list_remove(link_t *link)
|
||||
{
|
||||
link->next->prev = link->prev;
|
||||
link->prev->next = link->next;
|
||||
link_initialize(link);
|
||||
}
|
||||
|
||||
static inline Bool list_empty(link_t *head)
|
||||
{
|
||||
return head->next == head ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static inline void list_prepend(link_t *link, link_t *head)
|
||||
{
|
||||
link->next = head->next;
|
||||
link->prev = head;
|
||||
head->next->prev = link;
|
||||
head->next = link;
|
||||
}
|
||||
|
||||
static inline list_insert(link_t *new, link_t *old)
|
||||
{
|
||||
new->prev = old->prev;
|
||||
new->next = old;
|
||||
new->prev->next = new;
|
||||
old->prev = new;
|
||||
}
|
||||
32
drivers/video/agp/makefile
Normal file
32
drivers/video/agp/makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDRHD = -shared -T ld.x -s --file-alignment 32
|
||||
|
||||
INCLUDES = -I ../../include
|
||||
|
||||
HFILES:= ../../include/types.h \
|
||||
../../include/syscall.h \
|
||||
agp.h
|
||||
|
||||
SRC_DEP:= pci.inc \
|
||||
detect.inc \
|
||||
isoch.inc
|
||||
|
||||
AGP_SRC:= agp.c
|
||||
|
||||
|
||||
AGP = agp.dll
|
||||
|
||||
all: $(AGP)
|
||||
|
||||
$(AGP): agp.obj $(SRC_DEP) $(HFILES) Makefile
|
||||
wlink name agp.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @agp.lk
|
||||
kpack.exe agp.dll agp.drv
|
||||
|
||||
agp.obj : agp.c $(SRC_DEP) $(HFILES) Makefile
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -o agp.obj agp.c
|
||||
|
||||
|
||||
|
||||
128
drivers/video/agp/pci.inc
Normal file
128
drivers/video/agp/pci.inc
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
#define PCI_FIND_CAP_TTL 48
|
||||
|
||||
static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos,
|
||||
int cap, int *ttl)
|
||||
{
|
||||
u8_t id;
|
||||
|
||||
while ((*ttl)--)
|
||||
{
|
||||
pos = pciReadByte(pciTag, pos);
|
||||
if (pos < 0x40)
|
||||
break;
|
||||
pos &= ~3;
|
||||
id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID);
|
||||
if (id == 0xff)
|
||||
break;
|
||||
if (id == cap)
|
||||
return pos;
|
||||
pos += PCI_CAP_LIST_NEXT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap)
|
||||
{
|
||||
int ttl = PCI_FIND_CAP_TTL;
|
||||
|
||||
return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl);
|
||||
}
|
||||
|
||||
static int __pci_bus_find_cap_start(PCITAG pciTag)
|
||||
{
|
||||
u16_t status;
|
||||
u8_t hdr_type;
|
||||
|
||||
status = pciReadWord(pciTag, PCI_STATUS);
|
||||
if (!(status & PCI_STATUS_CAP_LIST))
|
||||
return 0;
|
||||
|
||||
hdr_type = pciReadByte(pciTag, 0x0E);
|
||||
switch (hdr_type)
|
||||
{
|
||||
case PCI_HEADER_TYPE_NORMAL:
|
||||
case PCI_HEADER_TYPE_BRIDGE:
|
||||
return PCI_CAPABILITY_LIST;
|
||||
case PCI_HEADER_TYPE_CARDBUS:
|
||||
return PCI_CB_CAPABILITY_LIST;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pci_find_capability(PCITAG pciTag, int cap)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = __pci_bus_find_cap_start(pciTag);
|
||||
if (pos)
|
||||
pos = __pci_find_next_cap(pciTag, pos, cap);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
PCITAG pci_find_class(u16_t class)
|
||||
{
|
||||
u32_t bus, last_bus;
|
||||
PCITAG tag;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return -1;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
u16_t devclass;
|
||||
|
||||
devclass = PciRead16(bus,devfn, 0x0A);
|
||||
|
||||
if( devclass != class)
|
||||
continue;
|
||||
|
||||
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
};
|
||||
};
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
PCITAG pci_get_device(u32_t vendor, u32_t device, PCITAG from)
|
||||
{
|
||||
u32_t bus, last_bus;
|
||||
u32_t devfn;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return -1;
|
||||
|
||||
bus = PCI_BUS_FROM_TAG(from);
|
||||
devfn = PCI_DFN_FROM_TAG(from);
|
||||
|
||||
devfn++;
|
||||
|
||||
for(;bus<=last_bus; bus++)
|
||||
{
|
||||
for(;devfn < 256;devfn++)
|
||||
{
|
||||
u32_t tmp;
|
||||
u32_t dev_vendor;
|
||||
u32_t dev_id;
|
||||
|
||||
tmp = PciRead32(bus,devfn, 0);
|
||||
|
||||
dev_vendor = (u16_t)tmp;
|
||||
dev_id = tmp >> 16;
|
||||
|
||||
if ((vendor == PCI_ANY_ID || dev_vendor == vendor))
|
||||
return pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
};
|
||||
};
|
||||
return -1;
|
||||
}
|
||||
|
||||
257
drivers/video/agp/syscall.h
Normal file
257
drivers/video/agp/syscall.h
Normal file
@@ -0,0 +1,257 @@
|
||||
|
||||
#define OS_BASE 0x80000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t handle;
|
||||
u32_t io_code;
|
||||
void *input;
|
||||
int inp_size;
|
||||
void *output;
|
||||
int out_size;
|
||||
}ioctl_t;
|
||||
|
||||
typedef int (__stdcall *srv_proc_t)(ioctl_t *);
|
||||
|
||||
#define ERR_OK 0
|
||||
#define ERR_PARAM -1
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int)__asm__("_drvEntry");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STDCALL __attribute__ ((stdcall)) __attribute__ ((dllimport))
|
||||
#define IMPORT __attribute__ ((dllimport))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SysMsgBoardStr __SysMsgBoardStr
|
||||
#define PciApi __PciApi
|
||||
//#define RegService __RegService
|
||||
#define CreateObject __CreateObject
|
||||
#define DestroyObject __DestroyObject
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PG_SW 0x003
|
||||
#define PG_NOCACHE 0x018
|
||||
|
||||
void* STDCALL AllocKernelSpace(size_t size)__asm__("AllocKernelSpace");
|
||||
void* STDCALL KernelAlloc(size_t size)__asm__("KernelAlloc");
|
||||
void* STDCALL KernelFree(void *mem)__asm__("KernelFree");
|
||||
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc");
|
||||
int STDCALL UserFree(void *mem)__asm__("UserFree");
|
||||
|
||||
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages");
|
||||
|
||||
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer");
|
||||
|
||||
u32_t STDCALL RegService(char *name, srv_proc_t proc)__asm__("RegService");
|
||||
|
||||
//void *CreateObject(u32 pid, size_t size);
|
||||
//void *DestroyObject(void *obj);
|
||||
|
||||
addr_t STDCALL MapIoMem(void* base,size_t size,u32_t flags)__asm__("MapIoMem");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static u32_t PciApi(int cmd);
|
||||
|
||||
u8_t STDCALL PciRead8 (u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead8");
|
||||
u16_t STDCALL PciRead16(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead16");
|
||||
u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
|
||||
|
||||
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8");
|
||||
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");
|
||||
u32_t STDCALL PciWrite32(u32_t bus, u32_t devfn, u32_t reg,u32_t val)__asm__("PciWrite32");
|
||||
|
||||
#define pciReadByte(tag, reg) \
|
||||
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadWord(tag, reg) \
|
||||
PciRead16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadLong(tag, reg) \
|
||||
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciWriteByte(tag, reg, val) \
|
||||
PciWrite8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteWord(tag, reg, val) \
|
||||
PciWrite16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteLong(tag, reg, val) \
|
||||
PciWrite32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int dbg_open(char *path);
|
||||
int dbgprintf(const char* format, ...);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern inline int GetScreenSize()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(1));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenBpp()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(2));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenPitch()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(3));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline u32_t GetPgAddr(void *mem)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__GetPgAddr \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (mem) );
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CommitPages"
|
||||
::"a" (page), "b"(mem),"c"(size>>12)
|
||||
:"edx" );
|
||||
__asm__ __volatile__ ("":::"eax","ebx","ecx");
|
||||
};
|
||||
|
||||
extern inline void UnmapPages(void *mem, size_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__UnmapPages"
|
||||
::"a" (mem), "c"(size>>12)
|
||||
:"edx");
|
||||
__asm__ __volatile__ ("":::"eax","ecx");
|
||||
};
|
||||
|
||||
extern inline void usleep(u32_t delay)
|
||||
{
|
||||
if( !delay )
|
||||
delay++;
|
||||
delay*=2000;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1:\n\t"
|
||||
"xorl %%eax, %%eax \n\t"
|
||||
"cpuid \n\t"
|
||||
"decl %%edi \n\t"
|
||||
"jnz 1b"
|
||||
:
|
||||
:"D"(delay)
|
||||
:"eax","ebx","ecx","edx");
|
||||
};
|
||||
|
||||
extern inline u32_t __PciApi(int cmd)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__PciApi"
|
||||
:"=a" (retval)
|
||||
:"a" (cmd)
|
||||
:"memory");
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void* __CreateObject(u32_t pid, size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CreateObject \n\t"
|
||||
:"=a" (retval)
|
||||
:"a" (size),"b"(pid)
|
||||
:"esi","edi", "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline void *__DestroyObject(void *obj)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__DestroyObject"
|
||||
:
|
||||
:"a" (obj)
|
||||
:"ebx","edx","esi","edi", "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
u32 __RegService(char *name, srv_proc_t proc)
|
||||
{
|
||||
u32 retval;
|
||||
|
||||
asm __volatile__
|
||||
(
|
||||
"pushl %%eax \n\t"
|
||||
"pushl %%ebx \n\t"
|
||||
"call *__imp__RegService \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (proc), "b" (name)
|
||||
:"memory"
|
||||
);
|
||||
return retval;
|
||||
};
|
||||
*/
|
||||
|
||||
extern inline u32_t safe_cli(void)
|
||||
{
|
||||
u32_t ifl;
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"popl %0\n\t"
|
||||
"cli\n"
|
||||
: "=r" (ifl));
|
||||
return ifl;
|
||||
}
|
||||
|
||||
extern inline void safe_sti(u32_t ifl)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"pushl %0\n\t"
|
||||
"popf\n"
|
||||
: : "r" (ifl)
|
||||
);
|
||||
}
|
||||
|
||||
extern inline void __clear (void * dst, unsigned len)
|
||||
{
|
||||
u32_t tmp;
|
||||
__asm__ __volatile__ (
|
||||
// "xorl %%eax, %%eax \n\t"
|
||||
"cld \n\t"
|
||||
"rep stosb \n"
|
||||
:"=c"(tmp),"=D"(tmp)
|
||||
:"a"(0),"c"(len),"D"(dst));
|
||||
__asm__ __volatile__ ("":::"ecx","edi");
|
||||
};
|
||||
|
||||
44
drivers/video/agp/types.h
Normal file
44
drivers/video/agp/types.h
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
#define NULL (void*)0
|
||||
|
||||
|
||||
typedef unsigned char u8_t;
|
||||
typedef unsigned short int u16_t;
|
||||
typedef unsigned int u32_t;
|
||||
typedef unsigned long long u64_t;
|
||||
|
||||
typedef unsigned int addr_t;
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef unsigned int count_t;
|
||||
typedef unsigned int eflags_t;
|
||||
|
||||
typedef unsigned int Bool;
|
||||
|
||||
#define TRUE (Bool)1
|
||||
#define FALSE (Bool)0
|
||||
|
||||
/*
|
||||
* min()/max() macros that also do
|
||||
* strict type-checking.. See the
|
||||
* "unnecessary" pointer comparison.
|
||||
*/
|
||||
#define min(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x < _y ? _x : _y; })
|
||||
|
||||
#define max(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x > _y ? _x : _y; })
|
||||
|
||||
|
||||
#define min_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
|
||||
#define max_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
|
||||
|
||||
|
||||
165
drivers/video/ati2d/accel_2d.h
Normal file
165
drivers/video/ati2d/accel_2d.h
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
#define PX_CREATE 1
|
||||
#define PX_DESTROY 2
|
||||
#define PX_CLEAR 3
|
||||
#define PX_DRAW_RECT 4
|
||||
#define PX_FILL_RECT 5
|
||||
#define PX_LINE 6
|
||||
#define PX_BLIT 7
|
||||
#define PX_BLIT_TRANSPARENT 8
|
||||
#define PX_BLIT_ALPHA 9
|
||||
|
||||
|
||||
|
||||
typedef unsigned int color_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
}pt_t;
|
||||
|
||||
/*********** Clipping **********/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int xmin;
|
||||
int ymin;
|
||||
int xmax;
|
||||
int ymax;
|
||||
}clip_t, *PTRclip;
|
||||
|
||||
#define CLIP_TOP 1
|
||||
#define CLIP_BOTTOM 2
|
||||
#define CLIP_RIGHT 4
|
||||
#define CLIP_LEFT 8
|
||||
|
||||
int LineClip ( clip_t *clip, int *x1, int *y1, int *x2, int *y2 );
|
||||
|
||||
int BlockClip( clip_t *clip, int *x1, int *y1, int *x2, int* y2 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
u32_t format;
|
||||
u32_t flags;
|
||||
size_t pitch;
|
||||
void *mapped;
|
||||
|
||||
u32_t handle;
|
||||
}pixmap_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
u32_t format;
|
||||
u32_t flags;
|
||||
size_t pitch;
|
||||
void *mapped;
|
||||
|
||||
unsigned pitch_offset;
|
||||
addr_t local;
|
||||
}local_pixmap_t;
|
||||
|
||||
#define PX_MEM_SYSTEM 0
|
||||
#define PX_MEM_LOCAL 1
|
||||
#define PX_MEM_GART 2
|
||||
|
||||
#define PX_MEM_MASK 3
|
||||
|
||||
#define PX_LOCK 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
local_pixmap_t *dstpix;
|
||||
|
||||
color_t color;
|
||||
}io_clear_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
local_pixmap_t *dstpix;
|
||||
|
||||
struct
|
||||
{
|
||||
int x0;
|
||||
int y0;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int x1;
|
||||
int y1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
};
|
||||
color_t color;
|
||||
color_t border;
|
||||
}io_draw_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
local_pixmap_t *dstpix;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
color_t bkcolor;
|
||||
color_t fcolor;
|
||||
|
||||
u32_t bmp0;
|
||||
u32_t bmp1;
|
||||
color_t border;
|
||||
}io_fill_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
local_pixmap_t *dstpix;
|
||||
int dst_x;
|
||||
int dst_y;
|
||||
|
||||
local_pixmap_t *srcpix;
|
||||
int src_x;
|
||||
int src_y;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
union {
|
||||
color_t key;
|
||||
color_t alpha;
|
||||
};
|
||||
}io_blit_t;
|
||||
|
||||
|
||||
static addr_t bind_pixmap(local_pixmap_t *pixmap);
|
||||
|
||||
|
||||
int CreatePixmap(pixmap_t *io);
|
||||
|
||||
int DestroyPixmap(pixmap_t *io);
|
||||
|
||||
int ClearPixmap(io_clear_t *io);
|
||||
|
||||
int Line(io_draw_t *draw);
|
||||
|
||||
int DrawRect(io_draw_t * draw);
|
||||
|
||||
int FillRect(io_fill_t * fill);
|
||||
|
||||
int Blit(io_blit_t* blit);
|
||||
|
||||
int BlitTransparent(io_blit_t* blit);
|
||||
|
||||
|
||||
|
||||
|
||||
889
drivers/video/ati2d/accel_2d.inc
Normal file
889
drivers/video/ati2d/accel_2d.inc
Normal file
@@ -0,0 +1,889 @@
|
||||
|
||||
|
||||
int ClearPixmap(io_clear_t *io)
|
||||
{
|
||||
u32_t *ring;
|
||||
|
||||
local_pixmap_t *dstpixmap;
|
||||
|
||||
dstpixmap = (io->dstpix == (void*)-1) ? &scr_pixmap : io->dstpix ;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(6);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, io->color);
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
OUTREG(R5XX_DST_Y_X, 0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(dstpixmap->width<<16)|dstpixmap->height);
|
||||
|
||||
#else
|
||||
BEGIN_RING(6);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(io->color);
|
||||
OUT_RING( 0 );
|
||||
OUT_RING((dstpixmap->width<<16)|dstpixmap->height);
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Line(io_draw_t *draw)
|
||||
{
|
||||
local_pixmap_t *dstpixmap;
|
||||
clip_t clip;
|
||||
int x0, y0, x1, y1;
|
||||
|
||||
dstpixmap = (draw->dstpix == (void*)-1) ? &scr_pixmap : draw->dstpix ;
|
||||
|
||||
x0 = draw->x0;
|
||||
y0 = draw->y0;
|
||||
|
||||
x1 = draw->x1;
|
||||
y1 = draw->y1;
|
||||
|
||||
clip.xmin = 0;
|
||||
clip.ymin = 0;
|
||||
clip.xmax = dstpixmap->width-1;
|
||||
clip.ymax = dstpixmap->height-1;
|
||||
|
||||
if ( !LineClip(&clip, &x0, &y0, &x1, &y1 ))
|
||||
{
|
||||
u32_t *ring, write;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(6);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DST_LINE_PATCOUNT, 0x55 << R5XX_BRES_CNTL_SHIFT);
|
||||
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, draw->color);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
|
||||
OUTREG(R5XX_DST_LINE_START,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_LINE_END,(y1<<16)|x1);
|
||||
#else
|
||||
BEGIN_RING(6);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_POLYLINE, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->color);
|
||||
OUT_RING((y0<<16)|x0);
|
||||
OUT_RING((y1<<16)|x1);
|
||||
COMMIT_RING();
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
};
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int DrawRect(io_draw_t* draw)
|
||||
{
|
||||
int x0, y0, x1, y1, xend, yend;
|
||||
|
||||
local_pixmap_t *dstpixmap;
|
||||
clip_t dst_clip;
|
||||
|
||||
dstpixmap = (draw->dstpix == (void*)-1) ? &scr_pixmap : draw->dstpix ;
|
||||
|
||||
x0 = draw->x0;
|
||||
y0 = draw->y0;
|
||||
|
||||
x1 = xend = x0 + draw->w - 1;
|
||||
y1 = yend = y0 + draw->h - 1;
|
||||
|
||||
dst_clip.xmin = 0;
|
||||
dst_clip.ymin = 0;
|
||||
dst_clip.xmax = dstpixmap->width-1;
|
||||
dst_clip.ymax = dstpixmap->height-1;
|
||||
|
||||
|
||||
// dbgprintf("draw rect x0:%d, y0:%d, x1:%d, y1:%d, color: %x\n",
|
||||
// x0, y0, x1, y1, draw->color);
|
||||
|
||||
if( ! BlockClip( &dst_clip, &x0, &y0, &x1, &y1))
|
||||
{
|
||||
u32_t *ring;
|
||||
int w, h;
|
||||
|
||||
w = x1 - x0 + 1;
|
||||
h = y1 - y0 + 1;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(7);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, draw->color);
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|h);
|
||||
|
||||
if( draw->color != draw->border)
|
||||
{
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, draw->border);
|
||||
|
||||
if( y0 == draw->y0)
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend )
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == draw->x0))
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend))
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
#else
|
||||
|
||||
BEGIN_RING(64);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->color);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((w<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
if( draw->color != draw->border)
|
||||
{
|
||||
if( y0 == draw->y0) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((w<<16)|1);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
|
||||
// y0++;
|
||||
// h--;
|
||||
}
|
||||
if( y1 == yend ) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y1);
|
||||
OUT_RING((w<<16)|1);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
// h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == draw->x0)) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x0<<16)|y0);
|
||||
OUT_RING((1<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
}
|
||||
if( (h > 0) && (x1 == xend)) {
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(draw->border);
|
||||
OUT_RING((x1<<16)|y0);
|
||||
OUT_RING((1<<16)|h);
|
||||
OUT_RING(CP_PACKET2());
|
||||
OUT_RING(CP_PACKET2());
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, draw->color);
|
||||
CP_REG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
CP_REG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|h);
|
||||
if( draw->color != draw->border)
|
||||
{
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, draw->border);
|
||||
CP_REG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
CP_REG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
|
||||
|
||||
if( y0 == draw->y0) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend ) {
|
||||
CP_REG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == draw->x0)) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend)) {
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
COMMIT_RING();
|
||||
#endif
|
||||
unlock_device();
|
||||
};
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int FillRect(io_fill_t *fill)
|
||||
{
|
||||
local_pixmap_t *dstpixmap;
|
||||
clip_t dst_clip;
|
||||
int x0, y0, x1, y1, xend, yend;
|
||||
|
||||
dstpixmap = (fill->dstpix == (void*)-1) ? &scr_pixmap : fill->dstpix ;
|
||||
|
||||
x0 = fill->x;
|
||||
y0 = fill->y;
|
||||
|
||||
xend = x1 = x0 + fill->w - 1;
|
||||
yend = y1 = y0 + fill->h - 1;
|
||||
|
||||
dst_clip.xmin = 0;
|
||||
dst_clip.ymin = 0;
|
||||
dst_clip.xmax = dstpixmap->width-1;
|
||||
dst_clip.ymax = dstpixmap->height-1;
|
||||
|
||||
// dbgprintf("fill rect x0:%d, y0:%d, x1:%d, y1:%d\n",
|
||||
// x0, y0, x1, y1);
|
||||
|
||||
if( ! BlockClip(&dst_clip, &x0, &y0, &x1, &y1))
|
||||
{
|
||||
u32_t *ring, write;
|
||||
|
||||
int w = x1 - x0 + 1;
|
||||
int h = y1 - y0 + 1;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(9);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R5XX_GMC_BRUSH_8X8_MONO_FG_BG |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
R5XX_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_BRUSH_BKGD_CLR, fill->bkcolor);
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, fill->fcolor);
|
||||
|
||||
OUTREG(R5XX_BRUSH_DATA0, fill->bmp0);
|
||||
OUTREG(R5XX_BRUSH_DATA1, fill->bmp1);
|
||||
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_HEIGHT_WIDTH,(h<<16)|w);
|
||||
|
||||
if( (fill->border & 0xFF000000) != 0)
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, fill->border);
|
||||
|
||||
if( y0 == fill->y)
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend )
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == fill->x))
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend))
|
||||
{
|
||||
FIFOWait(2);
|
||||
|
||||
OUTREG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
BEGIN_RING(9+10*2);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT, 7));
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R5XX_GMC_BRUSH_8X8_MONO_FG_BG |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
OUT_RING(fill->bkcolor);
|
||||
OUT_RING(fill->fcolor);
|
||||
|
||||
OUT_RING(fill->bmp0);
|
||||
OUT_RING(fill->bmp1);
|
||||
|
||||
OUT_RING((y0<<16)|x0);
|
||||
OUT_RING((y1<<16)|x1);
|
||||
|
||||
if( (fill->border & 0xFF000000) != 0)
|
||||
{
|
||||
CP_REG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
CP_REG(R5XX_DP_BRUSH_FRGD_CLR, fill->border);
|
||||
|
||||
if( y0 == fill->y)
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
y0++;
|
||||
h--;
|
||||
}
|
||||
if( y1 == yend )
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y1<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(w<<16)|1);
|
||||
h--;
|
||||
}
|
||||
if( (h > 0) && (x0 == fill->x))
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x0);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
if( (h > 0) && (x1 == xend))
|
||||
{
|
||||
CP_REG(R5XX_DST_Y_X,(y0<<16)|x1);
|
||||
CP_REG(R5XX_DST_WIDTH_HEIGHT,(1<<16)|h);
|
||||
}
|
||||
};
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
unlock_device();
|
||||
};
|
||||
return ERR_OK;
|
||||
};
|
||||
|
||||
|
||||
#define ADDRREG(addr) ((volatile u32_t *)(rhd.MMIOBase + (addr)))
|
||||
|
||||
|
||||
static int blit_host(u32_t dstpitch, int dstx, int dsty,
|
||||
u32_t src, int srcx, int srcy,
|
||||
int w, int h, int srcpitch, Bool trans, color_t key)
|
||||
{
|
||||
u32_t dp_cntl;
|
||||
color_t *src_addr;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
dp_cntl = RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_DP_SRC_SOURCE_HOST_DATA |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_S;
|
||||
|
||||
if( trans == FALSE )
|
||||
{
|
||||
dp_cntl|= R5XX_GMC_CLR_CMP_CNTL_DIS;
|
||||
FIFOWait(5);
|
||||
}
|
||||
else
|
||||
FIFOWait(8);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL, dp_cntl);
|
||||
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT |
|
||||
R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpitch);
|
||||
|
||||
if( trans )
|
||||
{
|
||||
OUTREG(R5XX_CLR_CMP_CLR_SRC, key);
|
||||
OUTREG(R5XX_CLR_CMP_MASK, R5XX_CLR_CMP_MSK);
|
||||
OUTREG(R5XX_CLR_CMP_CNTL, R5XX_SRC_CMP_EQ_COLOR |
|
||||
R5XX_CLR_CMP_SRC_SOURCE);
|
||||
};
|
||||
|
||||
OUTREG(RADEON_DST_Y_X, (dsty << 16) | (dstx & 0xffff));
|
||||
OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w);
|
||||
|
||||
src_addr = &((color_t*)src)[srcpitch*srcy/4+srcx];
|
||||
|
||||
while ( h-- )
|
||||
{
|
||||
color_t *tmp_src = src_addr;
|
||||
src_addr += srcpitch/4;
|
||||
|
||||
int left = w;
|
||||
|
||||
while( left )
|
||||
{
|
||||
volatile u32_t *d;
|
||||
|
||||
if( left > 8 )
|
||||
{
|
||||
int i;
|
||||
|
||||
R5xxFIFOWait(8);
|
||||
d = ADDRREG(RADEON_HOST_DATA0);
|
||||
|
||||
/* Unrolling doesn't improve performance */
|
||||
for ( i = 0; i < 8; i++)
|
||||
*d++ = *tmp_src++;
|
||||
left -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
R5xxFIFOWait(left);
|
||||
|
||||
if( h )
|
||||
d = ADDRREG(RADEON_HOST_DATA7) - (left - 1);
|
||||
else
|
||||
d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1);
|
||||
|
||||
for ( ; left; --left)
|
||||
*d++ = *tmp_src++;
|
||||
left = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
int Blit(io_blit_t *blit)
|
||||
{
|
||||
clip_t src_clip, dst_clip;
|
||||
|
||||
local_pixmap_t *srcpixmap;
|
||||
local_pixmap_t *dstpixmap;
|
||||
|
||||
u32_t srcpitchoffset;
|
||||
Bool need_sync = FALSE;
|
||||
|
||||
dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
|
||||
srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
|
||||
|
||||
src_clip.xmin = 0;
|
||||
src_clip.ymin = 0;
|
||||
src_clip.xmax = srcpixmap->width-1;
|
||||
src_clip.ymax = srcpixmap->height-1;
|
||||
|
||||
dst_clip.xmin = 0;
|
||||
dst_clip.ymin = 0;
|
||||
dst_clip.xmax = dstpixmap->width-1;
|
||||
dst_clip.ymax = dstpixmap->height-1;
|
||||
|
||||
if( !blit_clip(&dst_clip, &blit->dst_x, &blit->dst_y,
|
||||
&src_clip, &blit->src_x, &blit->src_y,
|
||||
&blit->w, &blit->h) )
|
||||
{
|
||||
u32_t *ring, write;
|
||||
/*
|
||||
if( (srcpixmap->flags & PX_MEM_MASK)==PX_MEM_SYSTEM)
|
||||
return blit_host(dstpixmap->pitch_offset,
|
||||
blit->dst_x, blit->dst_y,
|
||||
srcpixmap->mapped,
|
||||
blit->src_x, blit->src_y,
|
||||
blit->w, blit->h,
|
||||
srcpixmap->pitch,
|
||||
FALSE, 0 );
|
||||
*/
|
||||
|
||||
// if( (srcpixmap->flags & PX_MEM_MASK)==PX_MEM_SYSTEM)
|
||||
// {
|
||||
// srcpitchoffset = bind_pixmap(srcpixmap);
|
||||
// need_sync = TRUE;
|
||||
// }
|
||||
// else
|
||||
srcpitchoffset = srcpixmap->pitch_offset;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(7);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_S
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
OUTREG(R5XX_SRC_PITCH_OFFSET, srcpitchoffset);
|
||||
|
||||
OUTREG(R5XX_SRC_Y_X,(blit->src_y<<16)|blit->src_x);
|
||||
OUTREG(R5XX_DST_Y_X,(blit->dst_y<<16)|blit->dst_x);
|
||||
OUTREG(R5XX_DST_HEIGHT_WIDTH,(blit->h<<16)|blit->w);
|
||||
|
||||
#else
|
||||
BEGIN_RING(7);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT, 5));
|
||||
|
||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_S
|
||||
);
|
||||
|
||||
OUT_RING(srcpitchoffset);
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
|
||||
OUT_RING((blit->src_x<<16)|blit->src_y);
|
||||
OUT_RING((blit->dst_x<<16)|blit->dst_y);
|
||||
OUT_RING((blit->w<<16)|blit->h);
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
|
||||
if( need_sync == TRUE )
|
||||
R5xx2DIdleLocal();
|
||||
|
||||
unlock_device();
|
||||
|
||||
};
|
||||
return ERR_OK;
|
||||
};
|
||||
|
||||
|
||||
int BlitTransparent(io_blit_t *blit)
|
||||
{
|
||||
clip_t src_clip, dst_clip;
|
||||
|
||||
local_pixmap_t *srcpixmap;
|
||||
local_pixmap_t *dstpixmap;
|
||||
|
||||
u32_t srcpitchoffset;
|
||||
Bool need_sync = FALSE;
|
||||
|
||||
// dbgprintf("Transblit src: %x dst: %x\n",blit->srcpix, blit->dstpix);
|
||||
|
||||
dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
|
||||
srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
|
||||
|
||||
//dbgprintf("srcpixmap: %x dstpixmap: %x\n",srcpixmap, dstpixmap);
|
||||
|
||||
//dbgprintf("dst.width: %d dst.height: %d\n", dstpixmap->width,dstpixmap->height);
|
||||
//dbgprintf("src.width: %d src.height: %d\n", srcpixmap->width,srcpixmap->height);
|
||||
//dbgprintf("srcpitch: %x dstpitch: %x\n",
|
||||
// srcpixmap->pitch_offset,dstpixmap->pitch_offset);
|
||||
src_clip.xmin = 0;
|
||||
src_clip.ymin = 0;
|
||||
src_clip.xmax = srcpixmap->width-1;
|
||||
src_clip.ymax = srcpixmap->height-1;
|
||||
|
||||
dst_clip.xmin = 0;
|
||||
dst_clip.ymin = 0;
|
||||
dst_clip.xmax = dstpixmap->width-1;
|
||||
dst_clip.ymax = dstpixmap->height-1;
|
||||
|
||||
if( !blit_clip(&dst_clip, &blit->dst_x, &blit->dst_y,
|
||||
&src_clip, &blit->src_x, &blit->src_y,
|
||||
&blit->w, &blit->h) )
|
||||
{
|
||||
u32_t *ring, write;
|
||||
|
||||
|
||||
// if( (srcpixmap->flags & PX_MEM_MASK)==PX_MEM_SYSTEM)
|
||||
// {
|
||||
// srcpitchoffset = bind_pixmap(srcpixmap);
|
||||
// need_sync = TRUE;
|
||||
// }
|
||||
// else
|
||||
srcpitchoffset = srcpixmap->pitch_offset;
|
||||
|
||||
lock_device();
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(10);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_S
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
OUTREG(R5XX_CLR_CMP_CLR_SRC, blit->key);
|
||||
OUTREG(R5XX_CLR_CMP_MASK, R5XX_CLR_CMP_MSK);
|
||||
OUTREG(R5XX_CLR_CMP_CNTL, R5XX_SRC_CMP_EQ_COLOR | R5XX_CLR_CMP_SRC_SOURCE);
|
||||
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, dstpixmap->pitch_offset);
|
||||
OUTREG(R5XX_SRC_PITCH_OFFSET, srcpitchoffset);
|
||||
|
||||
OUTREG(R5XX_SRC_Y_X,(blit->src_y<<16)|blit->src_x);
|
||||
OUTREG(R5XX_DST_Y_X,(blit->dst_y<<16)|blit->dst_x);
|
||||
OUTREG(R5XX_DST_HEIGHT_WIDTH,(blit->h<<16)|blit->w);
|
||||
|
||||
#else
|
||||
|
||||
BEGIN_RING(10);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8));
|
||||
|
||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
R5XX_GMC_WR_MSK_DIS |
|
||||
R5XX_ROP3_S
|
||||
);
|
||||
|
||||
OUT_RING(srcpitchoffset);
|
||||
OUT_RING(dstpixmap->pitch_offset);
|
||||
|
||||
OUT_RING(R5XX_CLR_CMP_SRC_SOURCE | R5XX_SRC_CMP_EQ_COLOR);
|
||||
OUT_RING(blit->key);
|
||||
OUT_RING(0xFFFFFFFF);
|
||||
|
||||
OUT_RING((blit->src_x<<16)|blit->src_y);
|
||||
OUT_RING((blit->dst_x<<16)|blit->dst_y);
|
||||
OUT_RING((blit->w<<16)|blit->h);
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
#endif
|
||||
|
||||
if( need_sync == TRUE )
|
||||
R5xx2DIdleLocal();
|
||||
|
||||
unlock_device();
|
||||
|
||||
|
||||
};
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1218
drivers/video/ati2d/accel_3d.inc
Normal file
1218
drivers/video/ati2d/accel_3d.inc
Normal file
File diff suppressed because it is too large
Load Diff
181
drivers/video/ati2d/ati2d.c
Normal file
181
drivers/video/ati2d/ati2d.c
Normal file
@@ -0,0 +1,181 @@
|
||||
|
||||
|
||||
#define R300_PIO 0
|
||||
|
||||
|
||||
#define API_VERSION 0x01000100
|
||||
|
||||
#define SRV_GETVERSION 0
|
||||
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include "syscall.h"
|
||||
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include "atihw.h"
|
||||
|
||||
#include "accel_2d.h"
|
||||
|
||||
RHD_t rhd __attribute__ ((aligned (128))); /* reduce cache lock */
|
||||
|
||||
static clip_t clip;
|
||||
|
||||
static local_pixmap_t scr_pixmap;
|
||||
|
||||
|
||||
int __stdcall srv_2d(ioctl_t *io);
|
||||
|
||||
u32_t __stdcall drvEntry(int action)
|
||||
{
|
||||
RHDPtr rhdPtr;
|
||||
u32_t retval;
|
||||
|
||||
int i;
|
||||
|
||||
if(action != 1)
|
||||
return 0;
|
||||
|
||||
if(!dbg_open("/bd0/2/ati2d.log"))
|
||||
{
|
||||
printf("Can't open /rd/1/drivers/ati2d.log\nExit\n");
|
||||
return 0;
|
||||
}
|
||||
if( GetScreenBpp() != 32)
|
||||
{
|
||||
dbgprintf("32 bpp dispaly mode required !\nExit\t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((rhdPtr=FindPciDevice())==NULL)
|
||||
{
|
||||
dbgprintf("Device not found\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
dbgprintf("detect %s GART\n",
|
||||
rhd.gart_type == RADEON_IS_PCIE ? "PCIE":"PCI");
|
||||
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
if(rhd.memBase[i])
|
||||
dbgprintf("Memory base_%d 0x%x size 0x%x\n",
|
||||
i,rhd.memBase[i],(1<<rhd.memsize[i]));
|
||||
};
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
if(rhd.ioBase[i])
|
||||
dbgprintf("Io base_%d 0x%x size 0x%x\n",
|
||||
i,rhd.ioBase[i],(1<<rhd.memsize[i]));
|
||||
};
|
||||
if(!RHDPreInit())
|
||||
return 0;
|
||||
|
||||
R5xx2DInit();
|
||||
|
||||
Init3DEngine(&rhd);
|
||||
|
||||
retval = RegService("HDRAW", srv_2d);
|
||||
dbgprintf("reg service %s as: %x\n", "HDRAW", retval);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
int __stdcall srv_2d(ioctl_t *io)
|
||||
{
|
||||
u32_t *inp;
|
||||
u32_t *outp;
|
||||
|
||||
inp = io->input;
|
||||
outp = io->output;
|
||||
|
||||
switch(io->io_code)
|
||||
{
|
||||
case SRV_GETVERSION:
|
||||
if(io->out_size==4)
|
||||
{
|
||||
*outp = API_VERSION;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PX_CREATE:
|
||||
if(io->inp_size==7)
|
||||
return CreatePixmap((pixmap_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_DESTROY:
|
||||
if(io->inp_size==7)
|
||||
return DestroyPixmap((pixmap_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_CLEAR:
|
||||
if(io->inp_size==2)
|
||||
return ClearPixmap((io_clear_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_DRAW_RECT:
|
||||
if(io->inp_size==7)
|
||||
return DrawRect((io_draw_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_FILL_RECT:
|
||||
if(io->inp_size==10)
|
||||
return FillRect((io_fill_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_LINE:
|
||||
if(io->inp_size==6)
|
||||
return Line((io_draw_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_BLIT:
|
||||
if(io->inp_size==8)
|
||||
return Blit((io_blit_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_BLIT_TRANSPARENT:
|
||||
if(io->inp_size==9)
|
||||
return BlitTransparent((io_blit_t*)inp);
|
||||
break;
|
||||
|
||||
case PX_BLIT_ALPHA:
|
||||
if(io->inp_size==9)
|
||||
return RadeonComposite((io_blit_t*)inp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PARAM;
|
||||
};
|
||||
|
||||
return ERR_PARAM;
|
||||
}
|
||||
|
||||
|
||||
#include "init.c"
|
||||
#include "pci.c"
|
||||
#include "ati_mem.c"
|
||||
|
||||
#include "r500.inc"
|
||||
|
||||
#include "clip.inc"
|
||||
#include "pixmap.inc"
|
||||
#include "accel_2d.inc"
|
||||
#include "init_3d.inc"
|
||||
#include "blend.inc"
|
||||
|
||||
#if !R300_PIO
|
||||
|
||||
#include "init_cp.c"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
26
drivers/video/ati2d/ati2d.lk
Normal file
26
drivers/video/ati2d/ati2d.lk
Normal file
@@ -0,0 +1,26 @@
|
||||
IMP
|
||||
_KernelAlloc core.KernelAlloc,
|
||||
_KernelFree core.KernelFree,
|
||||
_UserAlloc core.UserAlloc,
|
||||
_UserFree core.UserFree,
|
||||
_AllocPages core.AllocPages,
|
||||
_CommitPages core.CommitPages,
|
||||
_UnmapPages core.UnmapPages,
|
||||
_MapIoMem core.MapIoMem,
|
||||
_GetPgAddr core.GetPgAddr,
|
||||
_CreateRingBuffer core.CreateRingBuffer,
|
||||
_PciApi core.PciApi,
|
||||
_PciRead8 core.PciRead8,
|
||||
_PciRead16 core.PciRead16,
|
||||
_PciRead32 core.PciRead32,
|
||||
_PciWrite32 core.PciWrite32,
|
||||
_RegService core.RegService,
|
||||
_WaitMutex core.WaitMutex,
|
||||
_Delay core.Delay,
|
||||
_ChangeTask core.ChangeTask,
|
||||
_SysMsgBoardStr core.SysMsgBoardStr
|
||||
|
||||
|
||||
FIL ati2d.obj,
|
||||
vsprintf.obj,
|
||||
icompute.obj
|
||||
225
drivers/video/ati2d/ati_mem.c
Normal file
225
drivers/video/ati2d/ati_mem.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
|
||||
/*
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
* The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
* initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
* This notice must be preserved.
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) 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
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS 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:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#define USED_BLOCK 1
|
||||
|
||||
#define list_for_each(entry, head) \
|
||||
for (entry = (head)->next; entry != head; entry = (entry)->next)
|
||||
|
||||
|
||||
/* Very simple allocator for GART memory, working on a static range
|
||||
* already mapped into each client's address space.
|
||||
*/
|
||||
|
||||
struct mem_block
|
||||
{
|
||||
struct mem_block *next;
|
||||
struct mem_block *prev;
|
||||
addr_t start;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* Initialize. How to check for an uninitialized heap?
|
||||
*/
|
||||
static int init_heap(struct mem_block **heap, int start, int size)
|
||||
{
|
||||
struct mem_block *blocks = malloc(sizeof(*blocks));
|
||||
|
||||
if (!blocks)
|
||||
return -1; //-ENOMEM;
|
||||
|
||||
*heap = malloc(sizeof(**heap));
|
||||
if (!*heap)
|
||||
{
|
||||
free(blocks);
|
||||
return -1; //-ENOMEM;
|
||||
}
|
||||
|
||||
blocks->start = start;
|
||||
blocks->size = size;
|
||||
blocks->next = blocks->prev = *heap;
|
||||
|
||||
__clear(*heap,sizeof(**heap));
|
||||
(*heap)->next = (*heap)->prev = blocks;
|
||||
(*heap)->start |= USED_BLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mem_block **get_heap(RHDPtr rhdPtr, int region)
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case RHD_MEM_GART:
|
||||
return &rhdPtr->gart_heap;
|
||||
case RHD_MEM_FB:
|
||||
return &rhdPtr->fb_heap;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct mem_block *split_block(struct mem_block *p, int size)
|
||||
{
|
||||
|
||||
/* Maybe cut off the end of an existing block */
|
||||
if (size < p->size)
|
||||
{
|
||||
struct mem_block *newblock = malloc(sizeof(*newblock));
|
||||
if (!newblock)
|
||||
goto out;
|
||||
newblock->start = p->start + size;
|
||||
newblock->size = p->size - size;
|
||||
newblock->next = p->next;
|
||||
newblock->prev = p;
|
||||
p->next->prev = newblock;
|
||||
p->next = newblock;
|
||||
p->size = size;
|
||||
p->start|=USED_BLOCK;
|
||||
}
|
||||
|
||||
out:
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct mem_block *alloc_block(struct mem_block *heap, int size)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
list_for_each(p, heap)
|
||||
{
|
||||
if ( !(p->start & USED_BLOCK) && size <= p->size)
|
||||
return split_block(p, size);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct mem_block *find_block(struct mem_block *heap, int start)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
list_for_each(p, heap)
|
||||
if ((p->start & ~USED_BLOCK) == start)
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void free_block(struct mem_block *p)
|
||||
{
|
||||
|
||||
/* Assumes a single contiguous range. Needs a special file_priv in
|
||||
* 'heap' to stop it being subsumed.
|
||||
*/
|
||||
|
||||
p->start &= ~USED_BLOCK;
|
||||
|
||||
if ( !(p->next->start & USED_BLOCK))
|
||||
{
|
||||
struct mem_block *q = p->next;
|
||||
p->size += q->size;
|
||||
p->next = q->next;
|
||||
p->next->prev = p;
|
||||
free(q);
|
||||
}
|
||||
|
||||
if ( !(p->prev->start & USED_BLOCK))
|
||||
{
|
||||
struct mem_block *q = p->prev;
|
||||
q->size += p->size;
|
||||
q->next = p->next;
|
||||
q->next->prev = q;
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
int rhdInitHeap(RHDPtr rhdPtr)
|
||||
{
|
||||
int base = rhdPtr->FbFreeStart;
|
||||
|
||||
return init_heap(&rhdPtr->fb_heap, base, rhdPtr->FbFreeSize);
|
||||
};
|
||||
|
||||
addr_t rhd_mem_alloc(RHDPtr rhdPtr,int region, int size)
|
||||
{
|
||||
struct mem_block *block, **heap;
|
||||
|
||||
heap = get_heap(rhdPtr, region);
|
||||
if (!heap || !*heap)
|
||||
return 0;
|
||||
|
||||
/* Make things easier on ourselves: all allocations at least
|
||||
* 4k aligned.
|
||||
*/
|
||||
|
||||
size = (size+4095) & ~4095;
|
||||
|
||||
block = alloc_block(*heap, size);
|
||||
|
||||
if (!block)
|
||||
return 0;
|
||||
|
||||
return (block->start & ~USED_BLOCK);
|
||||
}
|
||||
|
||||
int rhd_mem_free(RHDPtr rhdPtr, int region, addr_t offset)
|
||||
{
|
||||
struct mem_block *block, **heap;
|
||||
|
||||
heap = get_heap(rhdPtr, region);
|
||||
if (!heap || !*heap)
|
||||
return -1;
|
||||
|
||||
block = find_block(*heap, (int)offset);
|
||||
if (!block)
|
||||
return -1;
|
||||
|
||||
if ( !(block->start & USED_BLOCK))
|
||||
return -1;
|
||||
|
||||
free_block(block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dump_mem()
|
||||
{
|
||||
struct mem_block *p;
|
||||
struct mem_block **heap;
|
||||
|
||||
heap = &rhd.fb_heap;
|
||||
|
||||
list_for_each(p, *heap)
|
||||
{
|
||||
dbgprintf("block: %x next: %x prev: %x start: %x size:%x\n",
|
||||
p,p->next,p->prev,p->start,p->size);
|
||||
}
|
||||
}
|
||||
|
||||
385
drivers/video/ati2d/ati_pciids_gen.h
Normal file
385
drivers/video/ati2d/ati_pciids_gen.h
Normal file
@@ -0,0 +1,385 @@
|
||||
#define PCI_CHIP_RV380_3150 0x3150
|
||||
#define PCI_CHIP_RV380_3151 0x3151
|
||||
#define PCI_CHIP_RV380_3152 0x3152
|
||||
#define PCI_CHIP_RV380_3154 0x3154
|
||||
#define PCI_CHIP_RV380_3E50 0x3E50
|
||||
#define PCI_CHIP_RV380_3E54 0x3E54
|
||||
#define PCI_CHIP_RS100_4136 0x4136
|
||||
#define PCI_CHIP_RS200_4137 0x4137
|
||||
#define PCI_CHIP_R300_AD 0x4144
|
||||
#define PCI_CHIP_R300_AE 0x4145
|
||||
#define PCI_CHIP_R300_AF 0x4146
|
||||
#define PCI_CHIP_R300_AG 0x4147
|
||||
#define PCI_CHIP_R350_AH 0x4148
|
||||
#define PCI_CHIP_R350_AI 0x4149
|
||||
#define PCI_CHIP_R350_AJ 0x414A
|
||||
#define PCI_CHIP_R350_AK 0x414B
|
||||
#define PCI_CHIP_RV350_AP 0x4150
|
||||
#define PCI_CHIP_RV350_AQ 0x4151
|
||||
#define PCI_CHIP_RV360_AR 0x4152
|
||||
#define PCI_CHIP_RV350_AS 0x4153
|
||||
#define PCI_CHIP_RV350_AT 0x4154
|
||||
#define PCI_CHIP_RV350_4155 0x4155
|
||||
#define PCI_CHIP_RV350_AV 0x4156
|
||||
#define PCI_CHIP_MACH32 0x4158
|
||||
#define PCI_CHIP_RS250_4237 0x4237
|
||||
#define PCI_CHIP_R200_BB 0x4242
|
||||
#define PCI_CHIP_R200_BC 0x4243
|
||||
#define PCI_CHIP_RS100_4336 0x4336
|
||||
#define PCI_CHIP_RS200_4337 0x4337
|
||||
#define PCI_CHIP_MACH64CT 0x4354
|
||||
#define PCI_CHIP_MACH64CX 0x4358
|
||||
#define PCI_CHIP_RS250_4437 0x4437
|
||||
#define PCI_CHIP_MACH64ET 0x4554
|
||||
#define PCI_CHIP_MACH64GB 0x4742
|
||||
#define PCI_CHIP_MACH64GD 0x4744
|
||||
#define PCI_CHIP_MACH64GI 0x4749
|
||||
#define PCI_CHIP_MACH64GL 0x474C
|
||||
#define PCI_CHIP_MACH64GM 0x474D
|
||||
#define PCI_CHIP_MACH64GN 0x474E
|
||||
#define PCI_CHIP_MACH64GO 0x474F
|
||||
#define PCI_CHIP_MACH64GP 0x4750
|
||||
#define PCI_CHIP_MACH64GQ 0x4751
|
||||
#define PCI_CHIP_MACH64GR 0x4752
|
||||
#define PCI_CHIP_MACH64GS 0x4753
|
||||
#define PCI_CHIP_MACH64GT 0x4754
|
||||
#define PCI_CHIP_MACH64GU 0x4755
|
||||
#define PCI_CHIP_MACH64GV 0x4756
|
||||
#define PCI_CHIP_MACH64GW 0x4757
|
||||
#define PCI_CHIP_MACH64GX 0x4758
|
||||
#define PCI_CHIP_MACH64GY 0x4759
|
||||
#define PCI_CHIP_MACH64GZ 0x475A
|
||||
#define PCI_CHIP_RV250_If 0x4966
|
||||
#define PCI_CHIP_RV250_Ig 0x4967
|
||||
#define PCI_CHIP_R420_JH 0x4A48
|
||||
#define PCI_CHIP_R420_JI 0x4A49
|
||||
#define PCI_CHIP_R420_JJ 0x4A4A
|
||||
#define PCI_CHIP_R420_JK 0x4A4B
|
||||
#define PCI_CHIP_R420_JL 0x4A4C
|
||||
#define PCI_CHIP_R420_JM 0x4A4D
|
||||
#define PCI_CHIP_R420_JN 0x4A4E
|
||||
#define PCI_CHIP_R420_4A4F 0x4A4F
|
||||
#define PCI_CHIP_R420_JP 0x4A50
|
||||
#define PCI_CHIP_R481_4B49 0x4B49
|
||||
#define PCI_CHIP_R481_4B4A 0x4B4A
|
||||
#define PCI_CHIP_R481_4B4B 0x4B4B
|
||||
#define PCI_CHIP_R481_4B4C 0x4B4C
|
||||
#define PCI_CHIP_MACH64LB 0x4C42
|
||||
#define PCI_CHIP_MACH64LD 0x4C44
|
||||
#define PCI_CHIP_RAGE128LE 0x4C45
|
||||
#define PCI_CHIP_RAGE128LF 0x4C46
|
||||
#define PCI_CHIP_MACH64LG 0x4C47
|
||||
#define PCI_CHIP_MACH64LI 0x4C49
|
||||
#define PCI_CHIP_MACH64LM 0x4C4D
|
||||
#define PCI_CHIP_MACH64LN 0x4C4E
|
||||
#define PCI_CHIP_MACH64LP 0x4C50
|
||||
#define PCI_CHIP_MACH64LQ 0x4C51
|
||||
#define PCI_CHIP_MACH64LR 0x4C52
|
||||
#define PCI_CHIP_MACH64LS 0x4C53
|
||||
#define PCI_CHIP_RADEON_LW 0x4C57
|
||||
#define PCI_CHIP_RADEON_LX 0x4C58
|
||||
#define PCI_CHIP_RADEON_LY 0x4C59
|
||||
#define PCI_CHIP_RADEON_LZ 0x4C5A
|
||||
#define PCI_CHIP_RV250_Ld 0x4C64
|
||||
#define PCI_CHIP_RV250_Lf 0x4C66
|
||||
#define PCI_CHIP_RV250_Lg 0x4C67
|
||||
#define PCI_CHIP_RAGE128MF 0x4D46
|
||||
#define PCI_CHIP_RAGE128ML 0x4D4C
|
||||
#define PCI_CHIP_R300_ND 0x4E44
|
||||
#define PCI_CHIP_R300_NE 0x4E45
|
||||
#define PCI_CHIP_R300_NF 0x4E46
|
||||
#define PCI_CHIP_R300_NG 0x4E47
|
||||
#define PCI_CHIP_R350_NH 0x4E48
|
||||
#define PCI_CHIP_R350_NI 0x4E49
|
||||
#define PCI_CHIP_R360_NJ 0x4E4A
|
||||
#define PCI_CHIP_R350_NK 0x4E4B
|
||||
#define PCI_CHIP_RV350_NP 0x4E50
|
||||
#define PCI_CHIP_RV350_NQ 0x4E51
|
||||
#define PCI_CHIP_RV350_NR 0x4E52
|
||||
#define PCI_CHIP_RV350_NS 0x4E53
|
||||
#define PCI_CHIP_RV350_NT 0x4E54
|
||||
#define PCI_CHIP_RV350_NV 0x4E56
|
||||
#define PCI_CHIP_RAGE128PA 0x5041
|
||||
#define PCI_CHIP_RAGE128PB 0x5042
|
||||
#define PCI_CHIP_RAGE128PC 0x5043
|
||||
#define PCI_CHIP_RAGE128PD 0x5044
|
||||
#define PCI_CHIP_RAGE128PE 0x5045
|
||||
#define PCI_CHIP_RAGE128PF 0x5046
|
||||
#define PCI_CHIP_RAGE128PG 0x5047
|
||||
#define PCI_CHIP_RAGE128PH 0x5048
|
||||
#define PCI_CHIP_RAGE128PI 0x5049
|
||||
#define PCI_CHIP_RAGE128PJ 0x504A
|
||||
#define PCI_CHIP_RAGE128PK 0x504B
|
||||
#define PCI_CHIP_RAGE128PL 0x504C
|
||||
#define PCI_CHIP_RAGE128PM 0x504D
|
||||
#define PCI_CHIP_RAGE128PN 0x504E
|
||||
#define PCI_CHIP_RAGE128PO 0x504F
|
||||
#define PCI_CHIP_RAGE128PP 0x5050
|
||||
#define PCI_CHIP_RAGE128PQ 0x5051
|
||||
#define PCI_CHIP_RAGE128PR 0x5052
|
||||
#define PCI_CHIP_RAGE128PS 0x5053
|
||||
#define PCI_CHIP_RAGE128PT 0x5054
|
||||
#define PCI_CHIP_RAGE128PU 0x5055
|
||||
#define PCI_CHIP_RAGE128PV 0x5056
|
||||
#define PCI_CHIP_RAGE128PW 0x5057
|
||||
#define PCI_CHIP_RAGE128PX 0x5058
|
||||
#define PCI_CHIP_RADEON_QD 0x5144
|
||||
#define PCI_CHIP_RADEON_QE 0x5145
|
||||
#define PCI_CHIP_RADEON_QF 0x5146
|
||||
#define PCI_CHIP_RADEON_QG 0x5147
|
||||
#define PCI_CHIP_R200_QH 0x5148
|
||||
#define PCI_CHIP_R200_QL 0x514C
|
||||
#define PCI_CHIP_R200_QM 0x514D
|
||||
#define PCI_CHIP_RV200_QW 0x5157
|
||||
#define PCI_CHIP_RV200_QX 0x5158
|
||||
#define PCI_CHIP_RV100_QY 0x5159
|
||||
#define PCI_CHIP_RV100_QZ 0x515A
|
||||
#define PCI_CHIP_RN50_515E 0x515E
|
||||
#define PCI_CHIP_RAGE128RE 0x5245
|
||||
#define PCI_CHIP_RAGE128RF 0x5246
|
||||
#define PCI_CHIP_RAGE128RG 0x5247
|
||||
#define PCI_CHIP_RAGE128RK 0x524B
|
||||
#define PCI_CHIP_RAGE128RL 0x524C
|
||||
#define PCI_CHIP_RAGE128SE 0x5345
|
||||
#define PCI_CHIP_RAGE128SF 0x5346
|
||||
#define PCI_CHIP_RAGE128SG 0x5347
|
||||
#define PCI_CHIP_RAGE128SH 0x5348
|
||||
#define PCI_CHIP_RAGE128SK 0x534B
|
||||
#define PCI_CHIP_RAGE128SL 0x534C
|
||||
#define PCI_CHIP_RAGE128SM 0x534D
|
||||
#define PCI_CHIP_RAGE128SN 0x534E
|
||||
#define PCI_CHIP_RAGE128TF 0x5446
|
||||
#define PCI_CHIP_RAGE128TL 0x544C
|
||||
#define PCI_CHIP_RAGE128TR 0x5452
|
||||
#define PCI_CHIP_RAGE128TS 0x5453
|
||||
#define PCI_CHIP_RAGE128TT 0x5454
|
||||
#define PCI_CHIP_RAGE128TU 0x5455
|
||||
#define PCI_CHIP_RV370_5460 0x5460
|
||||
#define PCI_CHIP_RV370_5462 0x5462
|
||||
#define PCI_CHIP_RV370_5464 0x5464
|
||||
#define PCI_CHIP_R423_UH 0x5548
|
||||
#define PCI_CHIP_R423_UI 0x5549
|
||||
#define PCI_CHIP_R423_UJ 0x554A
|
||||
#define PCI_CHIP_R423_UK 0x554B
|
||||
#define PCI_CHIP_R430_554C 0x554C
|
||||
#define PCI_CHIP_R430_554D 0x554D
|
||||
#define PCI_CHIP_R430_554E 0x554E
|
||||
#define PCI_CHIP_R430_554F 0x554F
|
||||
#define PCI_CHIP_R423_5550 0x5550
|
||||
#define PCI_CHIP_R423_UQ 0x5551
|
||||
#define PCI_CHIP_R423_UR 0x5552
|
||||
#define PCI_CHIP_R423_UT 0x5554
|
||||
#define PCI_CHIP_RV410_564A 0x564A
|
||||
#define PCI_CHIP_RV410_564B 0x564B
|
||||
#define PCI_CHIP_RV410_564F 0x564F
|
||||
#define PCI_CHIP_RV410_5652 0x5652
|
||||
#define PCI_CHIP_RV410_5653 0x5653
|
||||
#define PCI_CHIP_RV410_5657 0x5657
|
||||
#define PCI_CHIP_MACH64VT 0x5654
|
||||
#define PCI_CHIP_MACH64VU 0x5655
|
||||
#define PCI_CHIP_MACH64VV 0x5656
|
||||
#define PCI_CHIP_RS300_5834 0x5834
|
||||
#define PCI_CHIP_RS300_5835 0x5835
|
||||
#define PCI_CHIP_RS480_5954 0x5954
|
||||
#define PCI_CHIP_RS480_5955 0x5955
|
||||
#define PCI_CHIP_RV280_5960 0x5960
|
||||
#define PCI_CHIP_RV280_5961 0x5961
|
||||
#define PCI_CHIP_RV280_5962 0x5962
|
||||
#define PCI_CHIP_RV280_5964 0x5964
|
||||
#define PCI_CHIP_RV280_5965 0x5965
|
||||
#define PCI_CHIP_RN50_5969 0x5969
|
||||
#define PCI_CHIP_RS482_5974 0x5974
|
||||
#define PCI_CHIP_RS485_5975 0x5975
|
||||
#define PCI_CHIP_RS400_5A41 0x5A41
|
||||
#define PCI_CHIP_RS400_5A42 0x5A42
|
||||
#define PCI_CHIP_RC410_5A61 0x5A61
|
||||
#define PCI_CHIP_RC410_5A62 0x5A62
|
||||
#define PCI_CHIP_RV370_5B60 0x5B60
|
||||
#define PCI_CHIP_RV370_5B62 0x5B62
|
||||
#define PCI_CHIP_RV370_5B63 0x5B63
|
||||
#define PCI_CHIP_RV370_5B64 0x5B64
|
||||
#define PCI_CHIP_RV370_5B65 0x5B65
|
||||
#define PCI_CHIP_RV280_5C61 0x5C61
|
||||
#define PCI_CHIP_RV280_5C63 0x5C63
|
||||
#define PCI_CHIP_R430_5D48 0x5D48
|
||||
#define PCI_CHIP_R430_5D49 0x5D49
|
||||
#define PCI_CHIP_R430_5D4A 0x5D4A
|
||||
#define PCI_CHIP_R480_5D4C 0x5D4C
|
||||
#define PCI_CHIP_R480_5D4D 0x5D4D
|
||||
#define PCI_CHIP_R480_5D4E 0x5D4E
|
||||
#define PCI_CHIP_R480_5D4F 0x5D4F
|
||||
#define PCI_CHIP_R480_5D50 0x5D50
|
||||
#define PCI_CHIP_R480_5D52 0x5D52
|
||||
#define PCI_CHIP_R423_5D57 0x5D57
|
||||
#define PCI_CHIP_RV410_5E48 0x5E48
|
||||
#define PCI_CHIP_RV410_5E4A 0x5E4A
|
||||
#define PCI_CHIP_RV410_5E4B 0x5E4B
|
||||
#define PCI_CHIP_RV410_5E4C 0x5E4C
|
||||
#define PCI_CHIP_RV410_5E4D 0x5E4D
|
||||
#define PCI_CHIP_RV410_5E4F 0x5E4F
|
||||
#define PCI_CHIP_R520_7100 0x7100
|
||||
#define PCI_CHIP_R520_7101 0x7101
|
||||
#define PCI_CHIP_R520_7102 0x7102
|
||||
#define PCI_CHIP_R520_7103 0x7103
|
||||
#define PCI_CHIP_R520_7104 0x7104
|
||||
#define PCI_CHIP_R520_7105 0x7105
|
||||
#define PCI_CHIP_R520_7106 0x7106
|
||||
#define PCI_CHIP_R520_7108 0x7108
|
||||
#define PCI_CHIP_R520_7109 0x7109
|
||||
#define PCI_CHIP_R520_710A 0x710A
|
||||
#define PCI_CHIP_R520_710B 0x710B
|
||||
#define PCI_CHIP_R520_710C 0x710C
|
||||
#define PCI_CHIP_R520_710E 0x710E
|
||||
#define PCI_CHIP_R520_710F 0x710F
|
||||
#define PCI_CHIP_RV515_7140 0x7140
|
||||
#define PCI_CHIP_RV515_7141 0x7141
|
||||
#define PCI_CHIP_RV515_7142 0x7142
|
||||
#define PCI_CHIP_RV515_7143 0x7143
|
||||
#define PCI_CHIP_RV515_7144 0x7144
|
||||
#define PCI_CHIP_RV515_7145 0x7145
|
||||
#define PCI_CHIP_RV515_7146 0x7146
|
||||
#define PCI_CHIP_RV515_7147 0x7147
|
||||
#define PCI_CHIP_RV515_7149 0x7149
|
||||
#define PCI_CHIP_RV515_714A 0x714A
|
||||
#define PCI_CHIP_RV515_714B 0x714B
|
||||
#define PCI_CHIP_RV515_714C 0x714C
|
||||
#define PCI_CHIP_RV515_714D 0x714D
|
||||
#define PCI_CHIP_RV515_714E 0x714E
|
||||
#define PCI_CHIP_RV515_714F 0x714F
|
||||
#define PCI_CHIP_RV515_7151 0x7151
|
||||
#define PCI_CHIP_RV515_7152 0x7152
|
||||
#define PCI_CHIP_RV515_7153 0x7153
|
||||
#define PCI_CHIP_RV515_715E 0x715E
|
||||
#define PCI_CHIP_RV515_715F 0x715F
|
||||
#define PCI_CHIP_RV515_7180 0x7180
|
||||
#define PCI_CHIP_RV515_7181 0x7181
|
||||
#define PCI_CHIP_RV515_7183 0x7183
|
||||
#define PCI_CHIP_RV515_7186 0x7186
|
||||
#define PCI_CHIP_RV515_7187 0x7187
|
||||
#define PCI_CHIP_RV515_7188 0x7188
|
||||
#define PCI_CHIP_RV515_718A 0x718A
|
||||
#define PCI_CHIP_RV515_718B 0x718B
|
||||
#define PCI_CHIP_RV515_718C 0x718C
|
||||
#define PCI_CHIP_RV515_718D 0x718D
|
||||
#define PCI_CHIP_RV515_718F 0x718F
|
||||
#define PCI_CHIP_RV515_7193 0x7193
|
||||
#define PCI_CHIP_RV515_7196 0x7196
|
||||
#define PCI_CHIP_RV515_719B 0x719B
|
||||
#define PCI_CHIP_RV515_719F 0x719F
|
||||
#define PCI_CHIP_RV530_71C0 0x71C0
|
||||
#define PCI_CHIP_RV530_71C1 0x71C1
|
||||
#define PCI_CHIP_RV530_71C2 0x71C2
|
||||
#define PCI_CHIP_RV530_71C3 0x71C3
|
||||
#define PCI_CHIP_RV530_71C4 0x71C4
|
||||
#define PCI_CHIP_RV530_71C5 0x71C5
|
||||
#define PCI_CHIP_RV530_71C6 0x71C6
|
||||
#define PCI_CHIP_RV530_71C7 0x71C7
|
||||
#define PCI_CHIP_RV530_71CD 0x71CD
|
||||
#define PCI_CHIP_RV530_71CE 0x71CE
|
||||
#define PCI_CHIP_RV530_71D2 0x71D2
|
||||
#define PCI_CHIP_RV530_71D4 0x71D4
|
||||
#define PCI_CHIP_RV530_71D5 0x71D5
|
||||
#define PCI_CHIP_RV530_71D6 0x71D6
|
||||
#define PCI_CHIP_RV530_71DA 0x71DA
|
||||
#define PCI_CHIP_RV530_71DE 0x71DE
|
||||
#define PCI_CHIP_RV515_7200 0x7200
|
||||
#define PCI_CHIP_RV515_7210 0x7210
|
||||
#define PCI_CHIP_RV515_7211 0x7211
|
||||
#define PCI_CHIP_R580_7240 0x7240
|
||||
#define PCI_CHIP_R580_7243 0x7243
|
||||
#define PCI_CHIP_R580_7244 0x7244
|
||||
#define PCI_CHIP_R580_7245 0x7245
|
||||
#define PCI_CHIP_R580_7246 0x7246
|
||||
#define PCI_CHIP_R580_7247 0x7247
|
||||
#define PCI_CHIP_R580_7248 0x7248
|
||||
#define PCI_CHIP_R580_7249 0x7249
|
||||
#define PCI_CHIP_R580_724A 0x724A
|
||||
#define PCI_CHIP_R580_724B 0x724B
|
||||
#define PCI_CHIP_R580_724C 0x724C
|
||||
#define PCI_CHIP_R580_724D 0x724D
|
||||
#define PCI_CHIP_R580_724E 0x724E
|
||||
#define PCI_CHIP_R580_724F 0x724F
|
||||
#define PCI_CHIP_RV570_7280 0x7280
|
||||
#define PCI_CHIP_RV560_7281 0x7281
|
||||
#define PCI_CHIP_RV560_7283 0x7283
|
||||
#define PCI_CHIP_R580_7284 0x7284
|
||||
#define PCI_CHIP_RV560_7287 0x7287
|
||||
#define PCI_CHIP_RV570_7288 0x7288
|
||||
#define PCI_CHIP_RV570_7289 0x7289
|
||||
#define PCI_CHIP_RV570_728B 0x728B
|
||||
#define PCI_CHIP_RV570_728C 0x728C
|
||||
#define PCI_CHIP_RV560_7290 0x7290
|
||||
#define PCI_CHIP_RV560_7291 0x7291
|
||||
#define PCI_CHIP_RV560_7293 0x7293
|
||||
#define PCI_CHIP_RV560_7297 0x7297
|
||||
#define PCI_CHIP_RS350_7834 0x7834
|
||||
#define PCI_CHIP_RS350_7835 0x7835
|
||||
#define PCI_CHIP_RS690_791E 0x791E
|
||||
#define PCI_CHIP_RS690_791F 0x791F
|
||||
#define PCI_CHIP_RS600_793F 0x793F
|
||||
#define PCI_CHIP_RS600_7941 0x7941
|
||||
#define PCI_CHIP_RS600_7942 0x7942
|
||||
#define PCI_CHIP_RS740_796C 0x796C
|
||||
#define PCI_CHIP_RS740_796D 0x796D
|
||||
#define PCI_CHIP_RS740_796E 0x796E
|
||||
#define PCI_CHIP_RS740_796F 0x796F
|
||||
#define PCI_CHIP_R600_9400 0x9400
|
||||
#define PCI_CHIP_R600_9401 0x9401
|
||||
#define PCI_CHIP_R600_9402 0x9402
|
||||
#define PCI_CHIP_R600_9403 0x9403
|
||||
#define PCI_CHIP_R600_9405 0x9405
|
||||
#define PCI_CHIP_R600_940A 0x940A
|
||||
#define PCI_CHIP_R600_940B 0x940B
|
||||
#define PCI_CHIP_R600_940F 0x940F
|
||||
#define PCI_CHIP_RV770_9440 0x9440
|
||||
#define PCI_CHIP_RV770_9441 0x9441
|
||||
#define PCI_CHIP_RV770_9442 0x9442
|
||||
#define PCI_CHIP_RV610_94C0 0x94C0
|
||||
#define PCI_CHIP_RV610_94C1 0x94C1
|
||||
#define PCI_CHIP_RV610_94C3 0x94C3
|
||||
#define PCI_CHIP_RV610_94C4 0x94C4
|
||||
#define PCI_CHIP_RV610_94C5 0x94C5
|
||||
#define PCI_CHIP_RV610_94C6 0x94C6
|
||||
#define PCI_CHIP_RV610_94C7 0x94C7
|
||||
#define PCI_CHIP_RV610_94C8 0x94C8
|
||||
#define PCI_CHIP_RV610_94C9 0x94C9
|
||||
#define PCI_CHIP_RV610_94CB 0x94CB
|
||||
#define PCI_CHIP_RV610_94CC 0x94CC
|
||||
#define PCI_CHIP_RV670_9500 0x9500
|
||||
#define PCI_CHIP_RV670_9501 0x9501
|
||||
#define PCI_CHIP_RV670_9505 0x9505
|
||||
#define PCI_CHIP_RV670_9507 0x9507
|
||||
#define PCI_CHIP_RV670_950F 0x950F
|
||||
#define PCI_CHIP_RV670_9511 0x9511
|
||||
#define PCI_CHIP_RV670_9515 0x9515
|
||||
#define PCI_CHIP_RV630_9580 0x9580
|
||||
#define PCI_CHIP_RV630_9581 0x9581
|
||||
#define PCI_CHIP_RV630_9583 0x9583
|
||||
#define PCI_CHIP_RV630_9586 0x9586
|
||||
#define PCI_CHIP_RV630_9587 0x9587
|
||||
#define PCI_CHIP_RV630_9588 0x9588
|
||||
#define PCI_CHIP_RV630_9589 0x9589
|
||||
#define PCI_CHIP_RV630_958A 0x958A
|
||||
#define PCI_CHIP_RV630_958B 0x958B
|
||||
#define PCI_CHIP_RV630_958C 0x958C
|
||||
#define PCI_CHIP_RV630_958D 0x958D
|
||||
#define PCI_CHIP_RV630_958E 0x958E
|
||||
#define PCI_CHIP_RV620_95C0 0x95C0
|
||||
#define PCI_CHIP_RV620_95C5 0x95C5
|
||||
#define PCI_CHIP_RV620_95C7 0x95C7
|
||||
#define PCI_CHIP_RV620_95C2 0x95C2
|
||||
#define PCI_CHIP_RV620_95C4 0x95C4
|
||||
#define PCI_CHIP_RV620_95CD 0x95CD
|
||||
#define PCI_CHIP_RV620_95CE 0x95CE
|
||||
#define PCI_CHIP_RV620_95CF 0x95CF
|
||||
#define PCI_CHIP_RV635_9590 0x9590
|
||||
#define PCI_CHIP_RV635_9596 0x9596
|
||||
#define PCI_CHIP_RV635_9597 0x9597
|
||||
#define PCI_CHIP_RV635_9598 0x9598
|
||||
#define PCI_CHIP_RV635_9599 0x9599
|
||||
#define PCI_CHIP_RV635_9591 0x9591
|
||||
#define PCI_CHIP_RV635_9593 0x9593
|
||||
#define PCI_CHIP_RS780_9610 0x9610
|
||||
#define PCI_CHIP_RS780_9611 0x9611
|
||||
#define PCI_CHIP_RS780_9612 0x9612
|
||||
#define PCI_CHIP_RS780_9613 0x9613
|
||||
569
drivers/video/ati2d/atihw.h
Normal file
569
drivers/video/ati2d/atihw.h
Normal file
@@ -0,0 +1,569 @@
|
||||
|
||||
typedef void *pointer;
|
||||
|
||||
typedef unsigned int memType;
|
||||
|
||||
typedef struct { float hi, lo; } range;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHIP_FAMILY_UNKNOW,
|
||||
CHIP_FAMILY_LEGACY,
|
||||
CHIP_FAMILY_RADEON,
|
||||
CHIP_FAMILY_RV100,
|
||||
CHIP_FAMILY_RS100, /* U1 (IGP320M) or A3 (IGP320)*/
|
||||
CHIP_FAMILY_RV200,
|
||||
CHIP_FAMILY_RS200, /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), RS250 (IGP 7000) */
|
||||
CHIP_FAMILY_R200,
|
||||
CHIP_FAMILY_RV250,
|
||||
CHIP_FAMILY_RS300, /* RS300/RS350 */
|
||||
CHIP_FAMILY_RV280,
|
||||
CHIP_FAMILY_R300,
|
||||
CHIP_FAMILY_R350,
|
||||
CHIP_FAMILY_RV350,
|
||||
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
|
||||
CHIP_FAMILY_R420, /* R420/R423/M18 */
|
||||
CHIP_FAMILY_RV410, /* RV410, M26 */
|
||||
CHIP_FAMILY_RS400, /* xpress 200, 200m (RS400) Intel */
|
||||
CHIP_FAMILY_RS480, /* xpress 200, 200m (RS410/480/482/485) AMD */
|
||||
CHIP_FAMILY_RV515, /* rv515 */
|
||||
CHIP_FAMILY_R520, /* r520 */
|
||||
CHIP_FAMILY_RV530, /* rv530 */
|
||||
CHIP_FAMILY_R580, /* r580 */
|
||||
CHIP_FAMILY_RV560, /* rv560 */
|
||||
CHIP_FAMILY_RV570, /* rv570 */
|
||||
CHIP_FAMILY_RS600,
|
||||
CHIP_FAMILY_RS690,
|
||||
CHIP_FAMILY_RS740,
|
||||
CHIP_FAMILY_R600, /* r600 */
|
||||
CHIP_FAMILY_R630,
|
||||
CHIP_FAMILY_RV610,
|
||||
CHIP_FAMILY_RV630,
|
||||
CHIP_FAMILY_RV670,
|
||||
CHIP_FAMILY_RV620,
|
||||
CHIP_FAMILY_RV635,
|
||||
CHIP_FAMILY_RS780,
|
||||
CHIP_FAMILY_RV770,
|
||||
CHIP_FAMILY_LAST
|
||||
} RADEONChipFamily;
|
||||
|
||||
#define IS_RV100_VARIANT ((rhdPtr->ChipFamily == CHIP_FAMILY_RV100) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RV200) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RS100) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RS200) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RV250) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RV280) || \
|
||||
(rhdPtr->ChipFamily == CHIP_FAMILY_RS300))
|
||||
|
||||
|
||||
#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV350) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R350) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV380) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R420) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV410) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS400) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS480))
|
||||
|
||||
#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
|
||||
|
||||
#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
|
||||
|
||||
#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R520) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV530) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R580) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV560) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV570))
|
||||
|
||||
#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV350) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R350) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV380) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_R420) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RV410) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS690) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS600) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS400) || \
|
||||
(info->ChipFamily == CHIP_FAMILY_RS480))
|
||||
|
||||
|
||||
typedef enum {
|
||||
CARD_PCI,
|
||||
CARD_AGP,
|
||||
CARD_PCIE
|
||||
} RADEONCardType;
|
||||
|
||||
enum radeon_chip_flags {
|
||||
RADEON_FAMILY_MASK = 0x0000ffffUL,
|
||||
RADEON_FLAGS_MASK = 0xffff0000UL,
|
||||
RADEON_IS_MOBILITY = 0x00010000UL,
|
||||
RADEON_IS_IGP = 0x00020000UL,
|
||||
RADEON_SINGLE_CRTC = 0x00040000UL,
|
||||
RADEON_IS_AGP = 0x00080000UL,
|
||||
RADEON_HAS_HIERZ = 0x00100000UL,
|
||||
RADEON_IS_PCIE = 0x00200000UL,
|
||||
RADEON_NEW_MEMMAP = 0x00400000UL,
|
||||
RADEON_IS_PCI = 0x00800000UL,
|
||||
RADEON_IS_IGPGART = 0x01000000UL,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Errata workarounds
|
||||
*/
|
||||
typedef enum {
|
||||
CHIP_ERRATA_R300_CG = 0x00000001,
|
||||
CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002,
|
||||
CHIP_ERRATA_PLL_DELAY = 0x00000004
|
||||
} RADEONErrata;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t pci_device_id;
|
||||
RADEONChipFamily chip_family;
|
||||
int mobility;
|
||||
int igp;
|
||||
int nocrtc2;
|
||||
int nointtvout;
|
||||
int singledac;
|
||||
} RADEONCardInfo;
|
||||
|
||||
|
||||
#define RHD_FB_BAR 0
|
||||
#define RHD_MMIO_BAR 2
|
||||
|
||||
#define RHD_MEM_GART 1
|
||||
#define RHD_MEM_FB 2
|
||||
|
||||
#define RADEON_DEFAULT_GART_SIZE 8 /* MB (must be 2^n and > 4MB) */
|
||||
#define R300_DEFAULT_GART_SIZE 32 /* MB (for R300 and above) */
|
||||
#define RADEON_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */
|
||||
#define RADEON_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */
|
||||
#define RADEON_DEFAULT_GART_TEX_SIZE 1 /* MB (must be page aligned) */
|
||||
|
||||
#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */
|
||||
|
||||
#define RADEON_DEFAULT_PCI_APER_SIZE 32 /* in MB */
|
||||
|
||||
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
|
||||
|
||||
#define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */
|
||||
#define RADEON_TIMEOUT 4000000 /* Fall out of wait loops after this count */
|
||||
|
||||
|
||||
typedef struct RHDRec
|
||||
{
|
||||
addr_t MMIOBase;
|
||||
size_t MMIOMapSize;
|
||||
|
||||
u32_t lock;
|
||||
|
||||
addr_t FbFreeStart;
|
||||
addr_t FbFreeSize;
|
||||
|
||||
/* visible part of the framebuffer */
|
||||
// unsigned int FbScanoutStart;
|
||||
// unsigned int FbScanoutSize;
|
||||
|
||||
// u32_t LinearAddr; /* Frame buffer physical address */
|
||||
|
||||
addr_t fbLocation; /* Frame buffer physical address */
|
||||
u32_t mc_fb_location;
|
||||
u32_t mc_agp_location;
|
||||
u32_t mc_agp_location_hi;
|
||||
|
||||
size_t videoRam;
|
||||
|
||||
u32_t MemCntl;
|
||||
u32_t BusCntl;
|
||||
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
|
||||
unsigned long FbSecureSize; /* Size of secured fb area at end of
|
||||
framebuffer */
|
||||
|
||||
RADEONChipFamily ChipFamily;
|
||||
RADEONErrata ChipErrata;
|
||||
|
||||
char *chipset;
|
||||
|
||||
Bool IsIGP;
|
||||
Bool IsMobility;
|
||||
Bool HasCRTC2;
|
||||
|
||||
u32_t bus;
|
||||
u32_t devfn;
|
||||
|
||||
PCITAG PciTag;
|
||||
u16_t PciDeviceID;
|
||||
|
||||
u16_t subvendor_id;
|
||||
u16_t subdevice_id;
|
||||
|
||||
RADEONCardType cardType; /* Current card is a PCI card */
|
||||
|
||||
u32_t memBase[6];
|
||||
u32_t ioBase[6];
|
||||
u32_t memtype[6];
|
||||
u32_t memsize[6];
|
||||
|
||||
struct mem_block *fb_heap;
|
||||
struct mem_block *gart_heap;
|
||||
|
||||
u32_t displayWidth;
|
||||
u32_t displayHeight;
|
||||
|
||||
u32_t gart_type;
|
||||
u32_t *gart_table;
|
||||
addr_t gart_table_dma;
|
||||
addr_t gart_vm_start;
|
||||
size_t gart_size;
|
||||
|
||||
u32_t* ringBase;
|
||||
u32_t ring_rp;
|
||||
u32_t ring_wp;
|
||||
u32_t ringSize;
|
||||
u32_t ring_avail;
|
||||
|
||||
u32_t bufSize;
|
||||
u32_t pciAperSize;
|
||||
u32_t CPusecTimeout;
|
||||
|
||||
int __xmin;
|
||||
int __ymin;
|
||||
int __xmax;
|
||||
int __ymax;
|
||||
|
||||
u32_t gui_control;
|
||||
u32_t dst_pitch_offset;
|
||||
u32_t surface_cntl;
|
||||
|
||||
|
||||
volatile u32_t host_rp __attribute__ ((aligned (128)));
|
||||
|
||||
volatile u32_t scratch0 __attribute__ ((aligned (128)));
|
||||
volatile u32_t scratch1;
|
||||
volatile u32_t scratch2;
|
||||
volatile u32_t scratch3;
|
||||
volatile u32_t scratch4;
|
||||
volatile u32_t scratch5;
|
||||
volatile u32_t scratch6;
|
||||
volatile u32_t scratch7;
|
||||
|
||||
int RamWidth __attribute__ ((aligned (128)));
|
||||
Bool IsDDR;
|
||||
|
||||
int num_gb_pipes;
|
||||
int has_tcl;
|
||||
|
||||
}RHD_t, *RHDPtr;
|
||||
|
||||
extern RHD_t rhd;
|
||||
|
||||
#define RADEON_CP_PACKET0 0x00000000
|
||||
#define RADEON_CP_PACKET1 0x40000000
|
||||
#define RADEON_CP_PACKET2 0x80000000
|
||||
#define RADEON_CP_PACKET3 0xC0000000
|
||||
|
||||
# define RADEON_CNTL_PAINT 0x00009100
|
||||
# define RADEON_CNTL_BITBLT 0x00009200
|
||||
# define RADEON_CNTL_TRANBLT 0x00009C00
|
||||
|
||||
# define RADEON_CNTL_PAINT_POLYLINE 0x00009500
|
||||
# define RADEON_CNTL_PAINT_MULTI 0x00009A00
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
#define BEGIN_ACCEL(n) FIFOWait(n)
|
||||
#define FINISH_ACCEL()
|
||||
#define COMMIT_RING()
|
||||
#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
|
||||
|
||||
#else
|
||||
|
||||
#define CP_PACKET0(reg, n) \
|
||||
(RADEON_CP_PACKET0 | ((n - 1 ) << 16) | ((reg) >> 2))
|
||||
|
||||
#define CP_PACKET1(reg0, reg1) \
|
||||
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
|
||||
|
||||
#define CP_PACKET2() \
|
||||
(RADEON_CP_PACKET2)
|
||||
|
||||
#define CP_PACKET3( pkt, n ) \
|
||||
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
|
||||
|
||||
|
||||
#define BEGIN_RING( req ) do { \
|
||||
int avail = rhd.ring_rp-rhd.ring_wp; \
|
||||
if (avail <=0 ) avail+= 0x4000; \
|
||||
if( (req)+128 > avail) \
|
||||
{ \
|
||||
rhd.ring_rp = INREG(RADEON_CP_RB_RPTR); \
|
||||
avail = rhd.ring_rp-rhd.ring_wp; \
|
||||
if (avail <= 0) avail+= 0x4000; \
|
||||
if( (req)+128 > avail){ \
|
||||
unlock_device(); \
|
||||
return 0; \
|
||||
}; \
|
||||
} \
|
||||
ring = &rhd.ringBase[rhd.ring_wp]; \
|
||||
}while(0)
|
||||
|
||||
#define ADVANCE_RING()
|
||||
|
||||
#define OUT_RING( x ) *ring++ = (x)
|
||||
|
||||
#define CP_REG(reg, val) \
|
||||
do { \
|
||||
ring[0] = CP_PACKET0((reg), 1); \
|
||||
ring[1] = (val); \
|
||||
ring+= 2; \
|
||||
} while (0)
|
||||
|
||||
#define DRM_MEMORYBARRIER() __asm__ volatile("lock; addl $0,0(%%esp)" : : : "memory");
|
||||
|
||||
#define COMMIT_RING() do { \
|
||||
rhd.ring_wp = (ring - rhd.ringBase) & 0x3FFF; \
|
||||
/* Flush writes to ring */ \
|
||||
DRM_MEMORYBARRIER(); \
|
||||
/*GET_RING_HEAD( dev_priv ); */ \
|
||||
OUTREG( RADEON_CP_RB_WPTR, rhd.ring_wp); \
|
||||
/* read from PCI bus to ensure correct posting */ \
|
||||
/* INREG( RADEON_CP_RB_RPTR ); */ \
|
||||
} while (0)
|
||||
|
||||
#define BEGIN_ACCEL(n) BEGIN_RING(2*(n))
|
||||
#define FINISH_ACCEL() COMMIT_RING()
|
||||
|
||||
#define OUT_ACCEL_REG(reg, val) CP_REG((reg), (val))
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int token; /* id of the token */
|
||||
const char * name; /* token name */
|
||||
} SymTabRec, *SymTabPtr;
|
||||
|
||||
|
||||
extern inline void lock_device()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__WaitMutex"
|
||||
::"b" (&rhd.lock));
|
||||
};
|
||||
|
||||
extern inline void unlock_device()
|
||||
{
|
||||
rhd.lock = 0;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
OUTREG8(u16_t offset, u8_t value)
|
||||
{
|
||||
*(volatile u8_t *)((u8_t *)(rhd.MMIOBase + offset)) = value;
|
||||
}
|
||||
|
||||
|
||||
extern inline u32_t INREG(u16_t offset)
|
||||
{
|
||||
return *(volatile u32_t *)((u8_t*)(rhd.MMIOBase + offset));
|
||||
}
|
||||
|
||||
|
||||
extern inline void OUTREG(u16_t offset, u32_t value)
|
||||
{
|
||||
*(volatile u32_t *)((u8_t *)(rhd.MMIOBase + offset)) = value;
|
||||
}
|
||||
|
||||
//#define OUTREG( offset, value) \
|
||||
// *(volatile u32_t *)((u8_t *)(rhd.MMIOBase + (u32_t)(offset))) = (u32_t)value
|
||||
|
||||
|
||||
extern inline u32_t _RHDRegRead(RHDPtr rhdPtr, u16_t offset)
|
||||
{
|
||||
return *(volatile u32_t *)((u8_t*)(rhdPtr->MMIOBase + offset));
|
||||
}
|
||||
|
||||
extern inline void
|
||||
MASKREG(u16_t offset, u32_t value, u32_t mask)
|
||||
{
|
||||
u32_t tmp;
|
||||
|
||||
tmp = INREG(offset);
|
||||
tmp &= ~mask;
|
||||
tmp |= (value & mask);
|
||||
OUTREG(offset, tmp);
|
||||
};
|
||||
|
||||
|
||||
#define INPLL( addr) RADEONINPLL( addr)
|
||||
|
||||
#define OUTPLL( addr, val) RADEONOUTPLL( addr, val)
|
||||
|
||||
|
||||
extern inline void
|
||||
_RHDRegWrite(RHDPtr rhdPtr, u16_t offset, u32_t value)
|
||||
{
|
||||
*(volatile u32_t *)((u8_t *)(rhdPtr->MMIOBase + offset)) = value;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
_RHDRegMask(RHDPtr rhdPtr, u16_t offset, u32_t value, u32_t mask)
|
||||
{
|
||||
u32_t tmp;
|
||||
|
||||
tmp = _RHDRegRead(rhdPtr, offset);
|
||||
tmp &= ~mask;
|
||||
tmp |= (value & mask);
|
||||
_RHDRegWrite(rhdPtr, offset, tmp);
|
||||
};
|
||||
|
||||
#define RHDRegRead(ptr, offset) _RHDRegRead((ptr)->rhdPtr, (offset))
|
||||
#define RHDRegWrite(ptr, offset, value) _RHDRegWrite((ptr)->rhdPtr, (offset), (value))
|
||||
#define RHDRegMask(ptr, offset, value, mask) _RHDRegMask((ptr)->rhdPtr, (offset), (value), (mask))
|
||||
|
||||
|
||||
#define RHDFUNC(ptr)
|
||||
|
||||
#define DBG(x) x
|
||||
// #define DBG(x)
|
||||
|
||||
#pragma pack (push,1)
|
||||
typedef struct s_cursor
|
||||
{
|
||||
u32_t magic; // 'CURS'
|
||||
void (*destroy)(struct s_cursor*); // destructor
|
||||
u32_t fd; // next object in list
|
||||
u32_t bk; // prev object in list
|
||||
u32_t pid; // owner id
|
||||
|
||||
void *base; // allocated memory
|
||||
u32_t hot_x; // hotspot coords
|
||||
u32_t hot_y;
|
||||
}cursor_t;
|
||||
#pragma pack (pop)
|
||||
|
||||
#define LOAD_FROM_FILE 0
|
||||
#define LOAD_FROM_MEM 1
|
||||
#define LOAD_INDIRECT 2
|
||||
|
||||
cursor_t *create_cursor(u32_t pid, void *src, u32_t flags);
|
||||
void __stdcall copy_cursor(void *img, void *src);
|
||||
void destroy_cursor(cursor_t *cursor);
|
||||
void __destroy_cursor(cursor_t *cursor); // wrap
|
||||
|
||||
void __stdcall r500_SelectCursor(cursor_t *cursor);
|
||||
void __stdcall r500_SetCursor(cursor_t *cursor, int x, int y);
|
||||
void __stdcall r500_CursorRestore(int x, int y);
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32_t x ;
|
||||
u32_t y ;
|
||||
} xPointFixed;
|
||||
|
||||
typedef u32_t xFixed_16_16;
|
||||
|
||||
typedef xFixed_16_16 xFixed;
|
||||
|
||||
#define XFIXED_BITS 16
|
||||
|
||||
#define xFixedToInt(f) (int) ((f) >> XFIXED_BITS)
|
||||
#define IntToxFixed(i) ((xFixed) (i) << XFIXED_BITS)
|
||||
|
||||
#define xFixedToFloat(f) (((float) (f)) / 65536)
|
||||
|
||||
#define PICT_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
|
||||
((type) << 16) | \
|
||||
((a) << 12) | \
|
||||
((r) << 8) | \
|
||||
((g) << 4) | \
|
||||
((b)))
|
||||
|
||||
#define PICT_FORMAT_A(f) (((f) >> 12) & 0x0f)
|
||||
#define PICT_FORMAT_RGB(f) (((f) ) & 0xfff)
|
||||
|
||||
#define PICT_TYPE_OTHER 0
|
||||
#define PICT_TYPE_A 1
|
||||
#define PICT_TYPE_ARGB 2
|
||||
#define PICT_TYPE_ABGR 3
|
||||
#define PICT_TYPE_COLOR 4
|
||||
#define PICT_TYPE_GRAY 5
|
||||
|
||||
typedef enum _PictFormatShort {
|
||||
PICT_a8r8g8b8 = PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8),
|
||||
PICT_x8r8g8b8 = PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8),
|
||||
PICT_a8b8g8r8 = PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8),
|
||||
PICT_x8b8g8r8 = PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8),
|
||||
|
||||
/* 24bpp formats */
|
||||
PICT_r8g8b8 = PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8),
|
||||
PICT_b8g8r8 = PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8),
|
||||
|
||||
/* 16bpp formats */
|
||||
PICT_r5g6b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5),
|
||||
PICT_b5g6r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5),
|
||||
|
||||
PICT_a1r5g5b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5),
|
||||
PICT_x1r5g5b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5),
|
||||
PICT_a1b5g5r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5),
|
||||
PICT_x1b5g5r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5),
|
||||
PICT_a4r4g4b4 = PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4),
|
||||
PICT_x4r4g4b4 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4),
|
||||
PICT_a4b4g4r4 = PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4),
|
||||
PICT_x4b4g4r4 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4),
|
||||
|
||||
/* 8bpp formats */
|
||||
PICT_a8 = PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0),
|
||||
PICT_r3g3b2 = PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2),
|
||||
PICT_b2g3r3 = PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2),
|
||||
PICT_a2r2g2b2 = PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2),
|
||||
PICT_a2b2g2r2 = PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2),
|
||||
|
||||
PICT_c8 = PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0),
|
||||
PICT_g8 = PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
PICT_x4a4 = PICT_FORMAT(8,PICT_TYPE_A,4,0,0,0),
|
||||
|
||||
PICT_x4c4 = PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0),
|
||||
PICT_x4g4 = PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
/* 4bpp formats */
|
||||
PICT_a4 = PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0),
|
||||
PICT_r1g2b1 = PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1),
|
||||
PICT_b1g2r1 = PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1),
|
||||
PICT_a1r1g1b1 = PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1),
|
||||
PICT_a1b1g1r1 = PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1),
|
||||
|
||||
PICT_c4 = PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0),
|
||||
PICT_g4 = PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
/* 1bpp formats */
|
||||
PICT_a1 = PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0),
|
||||
|
||||
PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
|
||||
} PictFormatShort;
|
||||
|
||||
void dump_mem();
|
||||
|
||||
|
||||
|
||||
RHDPtr FindPciDevice();
|
||||
|
||||
static __inline__ int drm_device_is_pcie(PCITAG pciTag);
|
||||
static void init_pipes(RHDPtr info);
|
||||
Bool init_cp(RHDPtr info);
|
||||
|
||||
Bool RHDPreInit();
|
||||
|
||||
void R5xx2DInit();
|
||||
|
||||
int Init3DEngine(RHDPtr info);
|
||||
|
||||
void init_gart(RHDPtr info);
|
||||
|
||||
int rhdInitHeap(RHDPtr rhdPtr);
|
||||
|
||||
|
||||
677
drivers/video/ati2d/blend.inc
Normal file
677
drivers/video/ati2d/blend.inc
Normal file
@@ -0,0 +1,677 @@
|
||||
|
||||
struct blendinfo {
|
||||
Bool dst_alpha;
|
||||
Bool src_alpha;
|
||||
u32_t blend_cntl;
|
||||
};
|
||||
|
||||
static struct blendinfo RadeonBlendOp[] = {
|
||||
/* 0 - Clear */
|
||||
{0, 0, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ZERO},
|
||||
/* 1 - Src */
|
||||
{0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO},
|
||||
/* 2 - Dst */
|
||||
{0, 0, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ONE},
|
||||
/* 3 - Over */
|
||||
{0, 1, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
|
||||
/* 4 - OverReverse */
|
||||
{1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE},
|
||||
/* 5 - In */
|
||||
{1, 0, RADEON_SRC_BLEND_GL_DST_ALPHA | RADEON_DST_BLEND_GL_ZERO},
|
||||
/* 6 - InReverse */
|
||||
{0, 1, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_SRC_ALPHA},
|
||||
/* 7 - Out */
|
||||
{1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ZERO},
|
||||
/* 8 - OutReverse */
|
||||
{0, 1, RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
|
||||
/* 9 - Atop */
|
||||
{1, 1, RADEON_SRC_BLEND_GL_DST_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
|
||||
/* 10- AtopReverse */
|
||||
{1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_SRC_ALPHA},
|
||||
/* 11 - Xor */
|
||||
{1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},
|
||||
/* 12 - Add */
|
||||
{0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE},
|
||||
};
|
||||
|
||||
|
||||
static Bool R300TextureSetup(RHDPtr info,local_pixmap_t *srcpix, int w, int h, int unit)
|
||||
{
|
||||
u32_t txfilter, txformat0, txformat1, txoffset, txpitch;
|
||||
|
||||
int i, pixel_shift;
|
||||
|
||||
|
||||
txpitch = srcpix->pitch;
|
||||
txoffset = (u32_t)srcpix->local;
|
||||
|
||||
if ((txoffset & 0x1f) != 0)
|
||||
dbgprintf("Bad texture offset 0x%x\n", (int)txoffset);
|
||||
if ((txpitch & 0x1f) != 0)
|
||||
dbgprintf("Bad texture pitch 0x%x\n", (int)txpitch);
|
||||
|
||||
/* TXPITCH = pixels (texels) per line - 1 */
|
||||
pixel_shift = 32 >> 4;
|
||||
txpitch >>= pixel_shift;
|
||||
txpitch -= 1;
|
||||
|
||||
txformat1 = R300_TX_FORMAT_A8R8G8B8;
|
||||
|
||||
txformat0 = ((((w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
|
||||
(((h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT));
|
||||
|
||||
if (IS_R500_3D && ((w - 1) & 0x800))
|
||||
txpitch |= R500_TXWIDTH_11;
|
||||
|
||||
if (IS_R500_3D && ((h - 1) & 0x800))
|
||||
txpitch |= R500_TXHEIGHT_11;
|
||||
|
||||
/* Use TXPITCH instead of TXWIDTH for address computations: we could
|
||||
* omit this if there is no padding, but there is no apparent advantage
|
||||
* in doing so.
|
||||
*/
|
||||
txformat0 |= R300_TXPITCH_EN;
|
||||
|
||||
txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL);
|
||||
|
||||
txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL);
|
||||
|
||||
txfilter |= (unit << R300_TX_ID_SHIFT);
|
||||
|
||||
txfilter |= (R300_TX_MAG_FILTER_NEAREST | R300_TX_MIN_FILTER_NEAREST);
|
||||
|
||||
|
||||
{
|
||||
u32_t *ring;
|
||||
|
||||
BEGIN_ACCEL(7);
|
||||
|
||||
OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
|
||||
OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
|
||||
OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
|
||||
OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
|
||||
OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
|
||||
OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
|
||||
// if (!pPict->repeat)
|
||||
OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
|
||||
|
||||
COMMIT_RING();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u32_t RADEONGetBlendCntl(int op, u32_t dst_format)
|
||||
{
|
||||
u32_t sblend, dblend;
|
||||
|
||||
|
||||
return RADEON_SRC_BLEND_GL_SRC_ALPHA | RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
|
||||
|
||||
Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
|
||||
local_pixmap_t *srcpix, int srcX, int srcY,
|
||||
int w, int h, int op)
|
||||
{
|
||||
u32_t dst_format, dst_offset, dst_pitch;
|
||||
u32_t txenable, colorpitch;
|
||||
u32_t blendcntl;
|
||||
int pixel_shift;
|
||||
u32_t *ring;
|
||||
|
||||
RHDPtr info = &rhd;
|
||||
|
||||
dst_format = R300_COLORFORMAT_ARGB8888;
|
||||
|
||||
dst_offset = (u32_t)dstpix->local;
|
||||
|
||||
dst_pitch = dstpix->pitch;
|
||||
|
||||
pixel_shift = 32 >> 4;
|
||||
|
||||
colorpitch = dst_pitch >> pixel_shift;
|
||||
|
||||
colorpitch |= dst_format;
|
||||
|
||||
if ((dst_offset & 0x0f) != 0)
|
||||
dbgprintf("Bad destination offset 0x%x\n", (int)dst_offset);
|
||||
if (((dst_pitch >> pixel_shift) & 0x7) != 0)
|
||||
dbgprintf("Bad destination pitch 0x%x\n", (int)dst_pitch);
|
||||
|
||||
|
||||
if (!R300TextureSetup(&rhd, srcpix, w, h, 0))
|
||||
return FALSE;
|
||||
|
||||
txenable = R300_TEX_0_ENABLE;
|
||||
|
||||
// RADEON_SWITCH_TO_3D();
|
||||
|
||||
/* setup the VAP */
|
||||
|
||||
BEGIN_ACCEL(7);
|
||||
|
||||
/* These registers define the number, type, and location of data submitted
|
||||
* to the PVS unit of GA input (when PVS is disabled)
|
||||
* DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is
|
||||
* enabled. This memory provides the imputs to the vertex shader program
|
||||
* and ordering is not important. When PVS/TCL is disabled, this field maps
|
||||
* directly to the GA input memory and the order is signifigant. In
|
||||
* PVS_BYPASS mode the order is as follows:
|
||||
* 0 Position
|
||||
* 1 Point Size
|
||||
* 2 Color 0
|
||||
* 3 Color 1
|
||||
* 4 Color 2
|
||||
* 5 Color 3
|
||||
* 6 Textures 0
|
||||
* 7 Textures 1
|
||||
* 8 Textures 2
|
||||
* 9 Textures 3 - 7
|
||||
* 14 Fog
|
||||
*/
|
||||
|
||||
OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
|
||||
((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
|
||||
(0 << R300_SKIP_DWORDS_0_SHIFT) |
|
||||
(0 << R300_DST_VEC_LOC_0_SHIFT) |
|
||||
R300_SIGNED_0 |
|
||||
(R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
|
||||
(0 << R300_SKIP_DWORDS_1_SHIFT) |
|
||||
(6 << R300_DST_VEC_LOC_1_SHIFT) |
|
||||
R300_LAST_VEC_1 |
|
||||
R300_SIGNED_1));
|
||||
|
||||
/* load the vertex shader
|
||||
* We pre-load vertex programs in RADEONInit3DEngine():
|
||||
* - exa no mask
|
||||
* - exa mask
|
||||
* - Xv
|
||||
* Here we select the offset of the vertex program we want to use
|
||||
*/
|
||||
if (info->has_tcl) {
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
|
||||
((3 << R300_PVS_FIRST_INST_SHIFT) |
|
||||
(4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
|
||||
(4 << R300_PVS_LAST_INST_SHIFT)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
|
||||
(4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
|
||||
}
|
||||
|
||||
/* Position and one or two sets of 2 texture coordinates */
|
||||
OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT); //VTX_COLOR_0_PRESENT
|
||||
OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1, (2 << R300_TEX_0_COMP_CNT_SHIFT));
|
||||
|
||||
OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
|
||||
OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
|
||||
FINISH_ACCEL();
|
||||
|
||||
/* setup pixel shader */
|
||||
|
||||
|
||||
/* setup pixel shader */
|
||||
if (IS_R300_3D)
|
||||
{
|
||||
u32_t output_fmt;
|
||||
int src_color, src_alpha;
|
||||
int mask_color, mask_alpha;
|
||||
|
||||
src_color = R300_ALU_RGB_SRC0_RGB;
|
||||
|
||||
src_alpha = R300_ALU_ALPHA_SRC0_A;
|
||||
|
||||
mask_color = R300_ALU_RGB_1_0;
|
||||
mask_alpha = R300_ALU_ALPHA_1_0;
|
||||
|
||||
/* shader output swizzling */
|
||||
output_fmt = (R300_OUT_FMT_C4_8 |
|
||||
R300_OUT_FMT_C0_SEL_BLUE |
|
||||
R300_OUT_FMT_C1_SEL_GREEN |
|
||||
R300_OUT_FMT_C2_SEL_RED |
|
||||
R300_OUT_FMT_C3_SEL_ALPHA);
|
||||
|
||||
|
||||
/* setup the rasterizer, load FS */
|
||||
BEGIN_ACCEL(10);
|
||||
/* 2 components: 2 for tex0 */
|
||||
OUT_ACCEL_REG(R300_RS_COUNT,
|
||||
((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
|
||||
R300_RS_COUNT_HIRES_EN));
|
||||
|
||||
OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
|
||||
|
||||
OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
|
||||
R300_ALU_CODE_SIZE(0) |
|
||||
R300_TEX_CODE_OFFSET(0) |
|
||||
R300_TEX_CODE_SIZE(0)));
|
||||
|
||||
OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
|
||||
(R300_ALU_START(0) |
|
||||
R300_ALU_SIZE(0) |
|
||||
R300_TEX_START(0) |
|
||||
R300_TEX_SIZE(0) |
|
||||
R300_RGBA_OUT));
|
||||
|
||||
// OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
|
||||
/* shader output swizzling */
|
||||
OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
|
||||
|
||||
/* tex inst for src texture is pre-loaded in RADEONInit3DEngine() */
|
||||
/* tex inst for mask texture is pre-loaded in RADEONInit3DEngine() */
|
||||
|
||||
/* RGB inst
|
||||
* temp addresses for texture inputs
|
||||
* ALU_RGB_ADDR0 is src tex (temp 0)
|
||||
* ALU_RGB_ADDR1 is mask tex (temp 1)
|
||||
* R300_ALU_RGB_OMASK - output components to write
|
||||
* R300_ALU_RGB_TARGET_A - render target
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(0),
|
||||
(R300_ALU_RGB_ADDR0(0) |
|
||||
R300_ALU_RGB_ADDR1(1) |
|
||||
R300_ALU_RGB_ADDR2(0) |
|
||||
R300_ALU_RGB_ADDRD(0) |
|
||||
R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
|
||||
R300_ALU_RGB_MASK_G |
|
||||
R300_ALU_RGB_MASK_B)) |
|
||||
R300_ALU_RGB_TARGET_A));
|
||||
/* RGB inst
|
||||
* ALU operation
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_US_ALU_RGB_INST(0),
|
||||
(R300_ALU_RGB_SEL_A(src_color) |
|
||||
R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
|
||||
R300_ALU_RGB_SEL_B(mask_color) |
|
||||
R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
|
||||
R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
|
||||
R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
|
||||
R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
|
||||
R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
|
||||
R300_ALU_RGB_CLAMP));
|
||||
/* Alpha inst
|
||||
* temp addresses for texture inputs
|
||||
* ALU_ALPHA_ADDR0 is src tex (0)
|
||||
* ALU_ALPHA_ADDR1 is mask tex (1)
|
||||
* R300_ALU_ALPHA_OMASK - output components to write
|
||||
* R300_ALU_ALPHA_TARGET_A - render target
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(0),
|
||||
(R300_ALU_ALPHA_ADDR0(0) |
|
||||
R300_ALU_ALPHA_ADDR1(1) |
|
||||
R300_ALU_ALPHA_ADDR2(0) |
|
||||
R300_ALU_ALPHA_ADDRD(0) |
|
||||
R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
|
||||
R300_ALU_ALPHA_TARGET_A |
|
||||
R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
|
||||
/* Alpha inst
|
||||
* ALU operation
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(0),
|
||||
(R300_ALU_ALPHA_SEL_A(src_alpha) |
|
||||
R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
|
||||
R300_ALU_ALPHA_SEL_B(mask_alpha) |
|
||||
R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
|
||||
R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
|
||||
R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
|
||||
R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
|
||||
R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
|
||||
R300_ALU_ALPHA_CLAMP));
|
||||
FINISH_ACCEL();
|
||||
}
|
||||
else
|
||||
{
|
||||
u32_t output_fmt;
|
||||
u32_t src_color, src_alpha;
|
||||
u32_t mask_color, mask_alpha;
|
||||
|
||||
src_color = (R500_ALU_RGB_R_SWIZ_A_R |
|
||||
R500_ALU_RGB_G_SWIZ_A_G |
|
||||
R500_ALU_RGB_B_SWIZ_A_B);
|
||||
|
||||
src_alpha = R500_ALPHA_SWIZ_A_A;
|
||||
|
||||
mask_color = (R500_ALU_RGB_R_SWIZ_B_1 |
|
||||
R500_ALU_RGB_G_SWIZ_B_1 |
|
||||
R500_ALU_RGB_B_SWIZ_B_1);
|
||||
mask_alpha = R500_ALPHA_SWIZ_B_1;
|
||||
|
||||
/* shader output swizzling */
|
||||
output_fmt = (R300_OUT_FMT_C4_8 |
|
||||
R300_OUT_FMT_C0_SEL_BLUE |
|
||||
R300_OUT_FMT_C1_SEL_GREEN |
|
||||
R300_OUT_FMT_C2_SEL_RED |
|
||||
R300_OUT_FMT_C3_SEL_ALPHA);
|
||||
|
||||
BEGIN_ACCEL(6);
|
||||
OUT_ACCEL_REG(R300_RS_COUNT,
|
||||
((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
|
||||
R300_RS_COUNT_HIRES_EN));
|
||||
|
||||
OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
|
||||
|
||||
OUT_ACCEL_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
|
||||
R500_US_CODE_END_ADDR(1)));
|
||||
OUT_ACCEL_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
|
||||
R500_US_CODE_RANGE_SIZE(1)));
|
||||
OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
|
||||
|
||||
OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
|
||||
COMMIT_RING();
|
||||
|
||||
BEGIN_ACCEL(13);
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
|
||||
/* tex inst for src texture */
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX |
|
||||
R500_INST_TEX_SEM_WAIT |
|
||||
R500_INST_RGB_WMASK_R |
|
||||
R500_INST_RGB_WMASK_G |
|
||||
R500_INST_RGB_WMASK_B |
|
||||
R500_INST_ALPHA_WMASK |
|
||||
R500_INST_RGB_CLAMP |
|
||||
R500_INST_ALPHA_CLAMP));
|
||||
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
|
||||
R500_TEX_INST_LD |
|
||||
R500_TEX_SEM_ACQUIRE |
|
||||
R500_TEX_IGNORE_UNCOVERED));
|
||||
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
|
||||
R500_TEX_SRC_S_SWIZ_R |
|
||||
R500_TEX_SRC_T_SWIZ_G |
|
||||
R500_TEX_DST_ADDR(0) |
|
||||
R500_TEX_DST_R_SWIZ_R |
|
||||
R500_TEX_DST_G_SWIZ_G |
|
||||
R500_TEX_DST_B_SWIZ_B |
|
||||
R500_TEX_DST_A_SWIZ_A));
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
|
||||
R500_DX_S_SWIZ_R |
|
||||
R500_DX_T_SWIZ_R |
|
||||
R500_DX_R_SWIZ_R |
|
||||
R500_DX_Q_SWIZ_R |
|
||||
R500_DY_ADDR(0) |
|
||||
R500_DY_S_SWIZ_R |
|
||||
R500_DY_T_SWIZ_R |
|
||||
R500_DY_R_SWIZ_R |
|
||||
R500_DY_Q_SWIZ_R));
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
|
||||
|
||||
/* ALU inst */
|
||||
/* *_OMASK* - output component write mask */
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT |
|
||||
R500_INST_TEX_SEM_WAIT |
|
||||
R500_INST_LAST |
|
||||
R500_INST_RGB_OMASK_R |
|
||||
R500_INST_RGB_OMASK_G |
|
||||
R500_INST_RGB_OMASK_B |
|
||||
R500_INST_ALPHA_OMASK |
|
||||
R500_INST_RGB_CLAMP |
|
||||
R500_INST_ALPHA_CLAMP));
|
||||
/* ALU inst
|
||||
* temp addresses for texture inputs
|
||||
* RGB_ADDR0 is src tex (temp 0)
|
||||
* RGB_ADDR1 is mask tex (temp 1)
|
||||
*/
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
|
||||
R500_RGB_ADDR1(1) |
|
||||
R500_RGB_ADDR2(0)));
|
||||
/* ALU inst
|
||||
* temp addresses for texture inputs
|
||||
* ALPHA_ADDR0 is src tex (temp 0)
|
||||
* ALPHA_ADDR1 is mask tex (temp 1)
|
||||
*/
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
|
||||
R500_ALPHA_ADDR1(1) |
|
||||
R500_ALPHA_ADDR2(0)));
|
||||
|
||||
/* R500_ALU_RGB_TARGET - RGB render target */
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 |
|
||||
src_color |
|
||||
R500_ALU_RGB_SEL_B_SRC1 |
|
||||
mask_color |
|
||||
R500_ALU_RGB_TARGET(0)));
|
||||
|
||||
/* R500_ALPHA_RGB_TARGET - alpha render target */
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD |
|
||||
R500_ALPHA_ADDRD(0) |
|
||||
R500_ALPHA_SEL_A_SRC0 |
|
||||
src_alpha |
|
||||
R500_ALPHA_SEL_B_SRC1 |
|
||||
mask_alpha |
|
||||
R500_ALPHA_TARGET(0)));
|
||||
|
||||
OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD |
|
||||
R500_ALU_RGBA_ADDRD(0) |
|
||||
R500_ALU_RGBA_R_SWIZ_0 |
|
||||
R500_ALU_RGBA_G_SWIZ_0 |
|
||||
R500_ALU_RGBA_B_SWIZ_0 |
|
||||
R500_ALU_RGBA_A_SWIZ_0));
|
||||
FINISH_ACCEL();
|
||||
}
|
||||
|
||||
BEGIN_ACCEL(3);
|
||||
OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
|
||||
OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
|
||||
|
||||
blendcntl = RADEONGetBlendCntl(op, PICT_a8r8g8b8);
|
||||
OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE |
|
||||
R300_READ_ENABLE);
|
||||
|
||||
FINISH_ACCEL();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define VTX_COUNT 4
|
||||
|
||||
static __inline__ u32_t F_TO_DW(float val)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
u32_t l;
|
||||
}tmp;
|
||||
tmp.f = val;
|
||||
return tmp.l;
|
||||
}
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
|
||||
|
||||
#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
|
||||
do { \
|
||||
OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstX); \
|
||||
OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstY); \
|
||||
OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcX); \
|
||||
OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcY); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
|
||||
|
||||
#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
|
||||
do { \
|
||||
OUT_RING_F(_dstX); \
|
||||
OUT_RING_F(_dstY); \
|
||||
OUT_RING_F(_srcX); \
|
||||
OUT_RING_F(_srcY); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
static int R300CompositeTile(int srcX, int srcY,
|
||||
int dstX, int dstY,
|
||||
int w, int h)
|
||||
{
|
||||
int vtx_count;
|
||||
xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
|
||||
xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
|
||||
|
||||
RHDPtr info = &rhd;
|
||||
|
||||
u32_t *ring;
|
||||
|
||||
srcTopLeft.x = IntToxFixed(srcX);
|
||||
srcTopLeft.y = IntToxFixed(srcY);
|
||||
srcTopRight.x = IntToxFixed(srcX + w);
|
||||
srcTopRight.y = IntToxFixed(srcY);
|
||||
srcBottomLeft.x = IntToxFixed(srcX);
|
||||
srcBottomLeft.y = IntToxFixed(srcY + h);
|
||||
srcBottomRight.x = IntToxFixed(srcX + w);
|
||||
srcBottomRight.y = IntToxFixed(srcY + h);
|
||||
|
||||
vtx_count = VTX_COUNT;
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
BEGIN_ACCEL(6 + vtx_count * 4);
|
||||
OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
|
||||
OUT_ACCEL_REG(RADEON_SE_VF_CNTL,
|
||||
(RADEON_VF_PRIM_TYPE_QUAD_LIST |
|
||||
RADEON_VF_PRIM_WALK_DATA |
|
||||
(4 << RADEON_VF_NUM_VERTICES_SHIFT)));
|
||||
|
||||
#else
|
||||
BEGIN_ACCEL(7 + 4 * vtx_count);
|
||||
OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
|
||||
|
||||
OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
|
||||
4 * vtx_count));
|
||||
OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
|
||||
RADEON_CP_VC_CNTL_PRIM_WALK_RING |
|
||||
(4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
|
||||
|
||||
#endif
|
||||
|
||||
VTX_OUT((float)dstX, (float)dstY,
|
||||
xFixedToFloat(srcTopLeft.x) / w, // info->texW[0],
|
||||
xFixedToFloat(srcTopLeft.y) / h); // info->texH[0]);
|
||||
|
||||
VTX_OUT((float)dstX, (float)(dstY + h),
|
||||
xFixedToFloat(srcBottomLeft.x) / w, // info->texW[0],
|
||||
xFixedToFloat(srcBottomLeft.y) / h); // info->texH[0]);
|
||||
|
||||
VTX_OUT((float)(dstX + w), (float)(dstY + h),
|
||||
xFixedToFloat(srcBottomRight.x) / w, // info->texW[0],
|
||||
xFixedToFloat(srcBottomRight.y) / h); // info->texH[0]);
|
||||
|
||||
VTX_OUT((float)(dstX + w), (float)dstY,
|
||||
xFixedToFloat(srcTopRight.x) / w, // info->texW[0],
|
||||
xFixedToFloat(srcTopRight.y) / h); // info->texH[0]);
|
||||
|
||||
/* flushing is pipelined, free/finish is not */
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL);
|
||||
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
|
||||
|
||||
COMMIT_RING();
|
||||
}
|
||||
|
||||
|
||||
#undef VTX_OUT
|
||||
#undef VTX_OUT_MASK
|
||||
|
||||
|
||||
int RadeonComposite( io_blit_t *blit)
|
||||
{
|
||||
int tileSrcY, tileMaskY, tileDstY;
|
||||
int remainingHeight;
|
||||
|
||||
local_pixmap_t *srcpixmap;
|
||||
local_pixmap_t *dstpixmap;
|
||||
|
||||
dbgprintf("Blit Alpha src: %x dst: %x\n",blit->srcpix, blit->dstpix);
|
||||
|
||||
dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
|
||||
srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
|
||||
|
||||
lock_device();
|
||||
|
||||
{
|
||||
u32_t *ring;
|
||||
|
||||
#if R300_PIO
|
||||
|
||||
FIFOWait(10);
|
||||
|
||||
OUTREG(R5XX_DP_GUI_MASTER_CNTL,
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET, srcpixmap->pitch_offset);
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, blit->alpha<<24);
|
||||
OUTREG(R5XX_DP_WRITE_MASK, 0xFF000000);
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
OUTREG(R5XX_DST_Y_X, 0);
|
||||
OUTREG(R5XX_DST_WIDTH_HEIGHT,(srcpixmap->width<<16)|srcpixmap->height);
|
||||
|
||||
OUTREG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN
|
||||
| RADEON_WAIT_HOST_IDLECLEAN );
|
||||
|
||||
OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF);
|
||||
OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_HOST_IDLECLEAN |
|
||||
RADEON_WAIT_2D_IDLECLEAN);
|
||||
|
||||
#else
|
||||
BEGIN_RING(2 + 6);
|
||||
|
||||
CP_REG(R5XX_DP_WRITE_MASK, 0xFF000000);
|
||||
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
|
||||
|
||||
OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_SOLID_COLOR |
|
||||
RADEON_GMC_DST_32BPP |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
R5XX_GMC_CLR_CMP_CNTL_DIS |
|
||||
R5XX_ROP3_P
|
||||
);
|
||||
|
||||
OUT_RING(srcpixmap->pitch_offset);
|
||||
OUT_RING(blit->alpha<<24);
|
||||
OUT_RING( 0 );
|
||||
OUT_RING((srcpixmap->width<<16)|srcpixmap->height);
|
||||
|
||||
COMMIT_RING();
|
||||
#endif
|
||||
RHDPtr info = &rhd;
|
||||
|
||||
FIFOWait(64);
|
||||
delay(2);
|
||||
|
||||
if( IS_R300_3D || IS_R500_3D )
|
||||
{
|
||||
R300PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
|
||||
srcpixmap, blit->src_x, blit->src_y,
|
||||
blit->w, blit->h, 3);
|
||||
|
||||
R300CompositeTile( blit->src_x, blit->src_y,
|
||||
blit->dst_x, blit->dst_y,
|
||||
blit->w, blit->h);
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV280) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS300) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R200))
|
||||
{
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
FIFOWait(64);
|
||||
delay(2);
|
||||
|
||||
unlock_device();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
181
drivers/video/ati2d/clip.inc
Normal file
181
drivers/video/ati2d/clip.inc
Normal file
@@ -0,0 +1,181 @@
|
||||
|
||||
#define CLIP_TOP 1
|
||||
#define CLIP_BOTTOM 2
|
||||
#define CLIP_RIGHT 4
|
||||
#define CLIP_LEFT 8
|
||||
|
||||
|
||||
static int _L1OutCode( clip_t *clip, int x, int y )
|
||||
/*=================================
|
||||
|
||||
Verify that a point is inside or outside the active viewport. */
|
||||
{
|
||||
int flag;
|
||||
|
||||
flag = 0;
|
||||
if( x < clip->xmin ) {
|
||||
flag |= CLIP_LEFT;
|
||||
} else if( x > clip->xmax ) {
|
||||
flag |= CLIP_RIGHT;
|
||||
}
|
||||
if( y < clip->ymin ) {
|
||||
flag |= CLIP_TOP;
|
||||
} else if( y > clip->ymax ) {
|
||||
flag |= CLIP_BOTTOM;
|
||||
}
|
||||
return( flag );
|
||||
}
|
||||
|
||||
|
||||
static void line_inter( int * x1, int* y1, int x2, int y2, int x )
|
||||
/*===========================================================================
|
||||
|
||||
Find the intersection of a line with a boundary of the viewport.
|
||||
(x1, y1) is outside and ( x2, y2 ) is inside the viewport.
|
||||
NOTE : the signs of denom and ( x - *x1 ) cancel out during division
|
||||
so make both of them positive before rounding. */
|
||||
{
|
||||
int numer;
|
||||
int denom;
|
||||
|
||||
denom = abs( x2 - *x1 );
|
||||
numer = 2L * (long)( y2 - *y1 ) * abs( x - *x1 );
|
||||
if( numer > 0 ) {
|
||||
numer += denom; /* round to closest pixel */
|
||||
} else {
|
||||
numer -= denom;
|
||||
}
|
||||
*y1 += numer / ( denom << 1 );
|
||||
*x1 = x;
|
||||
}
|
||||
|
||||
|
||||
int LineClip( clip_t *clip, int *x1, int *y1, int *x2, int *y2 )
|
||||
/*=============================================================
|
||||
|
||||
Clips the line with end points (x1,y1) and (x2,y2) to the active
|
||||
viewport using the Cohen-Sutherland clipping algorithm. Return the
|
||||
clipped coordinates and a decision drawing flag. */
|
||||
{
|
||||
int flag1;
|
||||
int flag2;
|
||||
|
||||
flag1 = _L1OutCode( clip, *x1, *y1 );
|
||||
flag2 = _L1OutCode( clip, *x2, *y2 );
|
||||
for( ;; ) {
|
||||
if( flag1 & flag2 ) break; /* trivially outside */
|
||||
if( flag1 == flag2 ) break; /* completely inside */
|
||||
if( flag1 == 0 ) { /* first point inside */
|
||||
if( flag2 & CLIP_TOP ) {
|
||||
line_inter( y2, x2, *y1, *x1, clip->ymin );
|
||||
} else if( flag2 & CLIP_BOTTOM ) {
|
||||
line_inter( y2, x2, *y1, *x1, clip->ymax );
|
||||
} else if( flag2 & CLIP_RIGHT ) {
|
||||
line_inter( x2, y2, *x1, *y1, clip->xmax );
|
||||
} else if( flag2 & CLIP_LEFT ) {
|
||||
line_inter( x2, y2, *x1, *y1, clip->xmin );
|
||||
}
|
||||
flag2 = _L1OutCode( clip, *x2, *y2 );
|
||||
} else { /* second point inside */
|
||||
if( flag1 & CLIP_TOP ) {
|
||||
line_inter( y1, x1, *y2, *x2, clip->ymin );
|
||||
} else if( flag1 & CLIP_BOTTOM ) {
|
||||
line_inter( y1, x1, *y2, *x2, clip->ymax );
|
||||
} else if( flag1 & CLIP_RIGHT ) {
|
||||
line_inter( x1, y1, *x2, *y2, clip->xmax );
|
||||
} else if( flag1 & CLIP_LEFT ) {
|
||||
line_inter( x1, y1, *x2, *y2, clip->xmin );
|
||||
}
|
||||
flag1 = _L1OutCode( clip, *x1, *y1 );
|
||||
}
|
||||
}
|
||||
return( flag1 & flag2 );
|
||||
}
|
||||
|
||||
|
||||
static void block_inter( clip_t *clip, int *x, int *y, int flag )
|
||||
/*======================================================
|
||||
|
||||
Find the intersection of a block with a boundary of the viewport. */
|
||||
{
|
||||
if( flag & CLIP_TOP ) {
|
||||
*y = clip->ymin;
|
||||
} else if( flag & CLIP_BOTTOM ) {
|
||||
*y = clip->ymax;
|
||||
} else if( flag & CLIP_RIGHT ) {
|
||||
*x = clip->xmax;
|
||||
} else if( flag & CLIP_LEFT ) {
|
||||
*x = clip->xmin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int BlockClip(clip_t *clip, int *x1, int *y1, int *x2, int* y2 )
|
||||
/*==============================================================
|
||||
|
||||
Clip a block with opposite corners (x1,y1) and (x2,y2) to the
|
||||
active viewport based on the Cohen-Sutherland algorithm for line
|
||||
clipping. Return the clipped coordinates and a decision drawing
|
||||
flag ( 0 draw : 1 don't draw ). */
|
||||
{
|
||||
int flag1;
|
||||
int flag2;
|
||||
|
||||
flag1 = _L1OutCode( clip, *x1, *y1 );
|
||||
flag2 = _L1OutCode( clip, *x2, *y2 );
|
||||
for( ;; ) {
|
||||
if( flag1 & flag2 ) break; /* trivially outside */
|
||||
if( flag1 == flag2 ) break; /* completely inside */
|
||||
if( flag1 == 0 ) {
|
||||
block_inter( clip, x2, y2, flag2 );
|
||||
flag2 = _L1OutCode( clip, *x2, *y2 );
|
||||
} else {
|
||||
block_inter( clip, x1, y1, flag1 );
|
||||
flag1 = _L1OutCode( clip, *x1, *y1 );
|
||||
}
|
||||
}
|
||||
return( flag1 & flag2 );
|
||||
}
|
||||
|
||||
|
||||
int blit_clip(clip_t *dst_clip,int *dst_x,int *dst_y,
|
||||
clip_t *src_clip,int *src_x, int *src_y,
|
||||
int *w, int *h)
|
||||
{
|
||||
int sx0, sy0, sx1, sy1;
|
||||
|
||||
sx0 = *src_x;
|
||||
sy0 = *src_y;
|
||||
|
||||
sx1 = sx0 + *w - 1;
|
||||
sy1 = sy0 + *h - 1;
|
||||
|
||||
|
||||
if( ! BlockClip( src_clip, &sx0, &sy0, &sx1, &sy1))
|
||||
{
|
||||
int dx0, dy0, dx1, dy1;
|
||||
|
||||
dx0 = *dst_x + sx0 - *src_x;
|
||||
dy0 = *dst_y + sy0 - *src_y;
|
||||
|
||||
dx1 = dx0 + sx1 - sx0;
|
||||
dy1 = dy0 + sy1 - sy0;
|
||||
|
||||
if( ! BlockClip( dst_clip, &dx0, &dy0, &dx1, &dy1))
|
||||
{
|
||||
*w = dx1 - dx0 + 1;
|
||||
*h = dy1 - dy0 + 1;
|
||||
|
||||
*src_x += dx0 - *dst_x;
|
||||
*src_y += dy0 - *dst_y;
|
||||
|
||||
*dst_x = dx0;
|
||||
*dst_y = dy0;
|
||||
|
||||
return 0;
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
1269
drivers/video/ati2d/init.c
Normal file
1269
drivers/video/ati2d/init.c
Normal file
File diff suppressed because it is too large
Load Diff
631
drivers/video/ati2d/init_3d.inc
Normal file
631
drivers/video/ati2d/init_3d.inc
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 on 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 (including the
|
||||
* next paragraph) 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
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
||||
* THEIR SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
|
||||
int Init3DEngine(RHDPtr info)
|
||||
{
|
||||
u32_t gb_tile_config, su_reg_dest, vap_cntl;
|
||||
|
||||
u32_t *ring;
|
||||
u32_t ifl;
|
||||
|
||||
// info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
FIFOWait(64);
|
||||
delay(2);
|
||||
|
||||
if (IS_R300_3D || IS_R500_3D) {
|
||||
|
||||
BEGIN_ACCEL(3);
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
|
||||
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
|
||||
FINISH_ACCEL();
|
||||
|
||||
gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
|
||||
|
||||
switch(info->num_gb_pipes)
|
||||
{
|
||||
case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
|
||||
case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
|
||||
case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
|
||||
default:
|
||||
case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
|
||||
}
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config);
|
||||
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
|
||||
OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
|
||||
OUT_ACCEL_REG(R300_GB_SELECT, 0);
|
||||
OUT_ACCEL_REG(R300_GB_ENABLE, 0);
|
||||
FINISH_ACCEL();
|
||||
|
||||
if (IS_R500_3D) {
|
||||
su_reg_dest = ((1 << info->num_gb_pipes) - 1);
|
||||
BEGIN_ACCEL(2);
|
||||
OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
|
||||
OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
|
||||
FINISH_ACCEL();
|
||||
}
|
||||
|
||||
BEGIN_ACCEL(3);
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
|
||||
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
|
||||
OUT_ACCEL_REG(R300_GB_MSPOS0, ((8 << R300_MS_X0_SHIFT) |
|
||||
(8 << R300_MS_Y0_SHIFT) |
|
||||
(8 << R300_MS_X1_SHIFT) |
|
||||
(8 << R300_MS_Y1_SHIFT) |
|
||||
(8 << R300_MS_X2_SHIFT) |
|
||||
(8 << R300_MS_Y2_SHIFT) |
|
||||
(8 << R300_MSBD0_Y_SHIFT) |
|
||||
(7 << R300_MSBD0_X_SHIFT)));
|
||||
OUT_ACCEL_REG(R300_GB_MSPOS1, ((8 << R300_MS_X3_SHIFT) |
|
||||
(8 << R300_MS_Y3_SHIFT) |
|
||||
(8 << R300_MS_X4_SHIFT) |
|
||||
(8 << R300_MS_Y4_SHIFT) |
|
||||
(8 << R300_MS_X5_SHIFT) |
|
||||
(8 << R300_MS_Y5_SHIFT) |
|
||||
(8 << R300_MSBD1_SHIFT)));
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL);
|
||||
OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE);
|
||||
OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST |
|
||||
R300_COLOR_ROUND_NEAREST));
|
||||
OUT_ACCEL_REG(R300_GA_COLOR_CONTROL, (R300_RGB0_SHADING_GOURAUD |
|
||||
R300_ALPHA0_SHADING_GOURAUD |
|
||||
R300_RGB1_SHADING_GOURAUD |
|
||||
R300_ALPHA1_SHADING_GOURAUD |
|
||||
R300_RGB2_SHADING_GOURAUD |
|
||||
R300_ALPHA2_SHADING_GOURAUD |
|
||||
R300_RGB3_SHADING_GOURAUD |
|
||||
R300_ALPHA3_SHADING_GOURAUD));
|
||||
OUT_ACCEL_REG(R300_GA_OFFSET, 0);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(R300_SU_TEX_WRAP, 0);
|
||||
OUT_ACCEL_REG(R300_SU_POLY_OFFSET_ENABLE, 0);
|
||||
OUT_ACCEL_REG(R300_SU_CULL_MODE, R300_FACE_NEG);
|
||||
OUT_ACCEL_REG(R300_SU_DEPTH_SCALE, 0x4b7fffff);
|
||||
OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
|
||||
FINISH_ACCEL();
|
||||
|
||||
/* setup the VAP */
|
||||
if (info->has_tcl)
|
||||
vap_cntl = ((5 << R300_PVS_NUM_SLOTS_SHIFT) |
|
||||
(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
|
||||
(9 << R300_VF_MAX_VTX_NUM_SHIFT));
|
||||
else
|
||||
vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
|
||||
(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
|
||||
(5 << R300_VF_MAX_VTX_NUM_SHIFT));
|
||||
|
||||
if (info->ChipFamily == CHIP_FAMILY_RV515)
|
||||
vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RV530) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV560) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV570))
|
||||
vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R420))
|
||||
vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R520) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R580))
|
||||
vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
|
||||
else
|
||||
vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
|
||||
|
||||
if (info->has_tcl)
|
||||
BEGIN_ACCEL(15);
|
||||
else
|
||||
BEGIN_ACCEL(9);
|
||||
OUT_ACCEL_REG(R300_VAP_VTX_STATE_CNTL, 0);
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
|
||||
|
||||
if (info->has_tcl)
|
||||
OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
|
||||
else
|
||||
OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
|
||||
OUT_ACCEL_REG(R300_VAP_CNTL, vap_cntl);
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
|
||||
OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
|
||||
OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
|
||||
|
||||
OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
|
||||
((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
|
||||
((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
|
||||
<< R300_WRITE_ENA_0_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
|
||||
((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
|
||||
<< R300_WRITE_ENA_1_SHIFT)));
|
||||
OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
|
||||
((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
|
||||
(R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_2_SHIFT) |
|
||||
((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
|
||||
<< R300_WRITE_ENA_2_SHIFT)));
|
||||
|
||||
if (info->has_tcl) {
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0);
|
||||
OUT_ACCEL_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
|
||||
OUT_ACCEL_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
|
||||
OUT_ACCEL_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
|
||||
OUT_ACCEL_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
|
||||
OUT_ACCEL_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
|
||||
}
|
||||
FINISH_ACCEL();
|
||||
|
||||
/* pre-load the vertex shaders */
|
||||
if (info->has_tcl) {
|
||||
/* exa mask/Xv bicubic shader program
|
||||
|
||||
dcl_position v0
|
||||
dcl_texcoord v1
|
||||
dcl_texcoord1 v2
|
||||
|
||||
mov oPos, v0
|
||||
mov oT0, v1
|
||||
mov oT1, v2 */
|
||||
|
||||
|
||||
BEGIN_ACCEL(13);
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
|
||||
/* PVS inst 0 */
|
||||
OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(0) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
|
||||
/* PVS inst 1 */
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(1) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
|
||||
/* PVS inst 2 */
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(2) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(7) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(7) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(7) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(9);
|
||||
|
||||
/* exa no mask instruction
|
||||
|
||||
dcl_position v0
|
||||
dcl_texcoord v1
|
||||
|
||||
mov oPos, v0
|
||||
mov oT0, v1 */
|
||||
|
||||
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 3);
|
||||
/* PVS inst 0 */
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(0) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
|
||||
/* PVS inst 1 */
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(1) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
FINISH_ACCEL();
|
||||
|
||||
/* Xv shader program */
|
||||
BEGIN_ACCEL(9);
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 5);
|
||||
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(0) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(0) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_DST_OPCODE(R300_VE_ADD) |
|
||||
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
|
||||
R300_PVS_DST_OFFSET(1) |
|
||||
R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
|
||||
R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
|
||||
(R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
|
||||
R300_PVS_SRC_OFFSET(6) |
|
||||
R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
|
||||
R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
|
||||
FINISH_ACCEL();
|
||||
}
|
||||
|
||||
/* pre-load the RS instructions */
|
||||
BEGIN_ACCEL(4);
|
||||
if (IS_R300_3D) {
|
||||
/* rasterizer source table
|
||||
* R300_RS_TEX_PTR is the offset into the input RS stream
|
||||
* 0,1 are tex0
|
||||
* 2,3 are tex1
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_RS_IP_0,
|
||||
(R300_RS_TEX_PTR(0) |
|
||||
R300_RS_SEL_S(R300_RS_SEL_C0) |
|
||||
R300_RS_SEL_T(R300_RS_SEL_C1) |
|
||||
R300_RS_SEL_R(R300_RS_SEL_K0) |
|
||||
R300_RS_SEL_Q(R300_RS_SEL_K1)));
|
||||
OUT_ACCEL_REG(R300_RS_IP_1,
|
||||
(R300_RS_TEX_PTR(2) |
|
||||
R300_RS_SEL_S(R300_RS_SEL_C0) |
|
||||
R300_RS_SEL_T(R300_RS_SEL_C1) |
|
||||
R300_RS_SEL_R(R300_RS_SEL_K0) |
|
||||
R300_RS_SEL_Q(R300_RS_SEL_K1)));
|
||||
/* src tex */
|
||||
/* R300_INST_TEX_ID - select the RS source table entry
|
||||
* R300_INST_TEX_ADDR - the FS temp register for the texture data
|
||||
*/
|
||||
OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
|
||||
R300_RS_INST_TEX_CN_WRITE |
|
||||
R300_INST_TEX_ADDR(0)));
|
||||
/* mask tex */
|
||||
OUT_ACCEL_REG(R300_RS_INST_1, (R300_INST_TEX_ID(1) |
|
||||
R300_RS_INST_TEX_CN_WRITE |
|
||||
R300_INST_TEX_ADDR(1)));
|
||||
|
||||
} else {
|
||||
/* rasterizer source table
|
||||
* R300_RS_TEX_PTR is the offset into the input RS stream
|
||||
* 0,1 are tex0
|
||||
* 2,3 are tex1
|
||||
*/
|
||||
OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
|
||||
(1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
|
||||
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
|
||||
(R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
|
||||
|
||||
OUT_ACCEL_REG(R500_RS_IP_1, ((2 << R500_RS_IP_TEX_PTR_S_SHIFT) |
|
||||
(3 << R500_RS_IP_TEX_PTR_T_SHIFT) |
|
||||
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
|
||||
(R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
|
||||
/* src tex */
|
||||
/* R500_RS_INST_TEX_ID_SHIFT - select the RS source table entry
|
||||
* R500_RS_INST_TEX_ADDR_SHIFT - the FS temp register for the texture data
|
||||
*/
|
||||
OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
|
||||
R500_RS_INST_TEX_CN_WRITE |
|
||||
(0 << R500_RS_INST_TEX_ADDR_SHIFT)));
|
||||
/* mask tex */
|
||||
OUT_ACCEL_REG(R500_RS_INST_1, ((1 << R500_RS_INST_TEX_ID_SHIFT) |
|
||||
R500_RS_INST_TEX_CN_WRITE |
|
||||
(1 << R500_RS_INST_TEX_ADDR_SHIFT)));
|
||||
}
|
||||
FINISH_ACCEL();
|
||||
|
||||
if (IS_R300_3D)
|
||||
BEGIN_ACCEL(4);
|
||||
else {
|
||||
BEGIN_ACCEL(6);
|
||||
OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
|
||||
OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
|
||||
}
|
||||
OUT_ACCEL_REG(R300_US_W_FMT, 0);
|
||||
OUT_ACCEL_REG(R300_US_OUT_FMT_1, (R300_OUT_FMT_UNUSED |
|
||||
R300_OUT_FMT_C0_SEL_BLUE |
|
||||
R300_OUT_FMT_C1_SEL_GREEN |
|
||||
R300_OUT_FMT_C2_SEL_RED |
|
||||
R300_OUT_FMT_C3_SEL_ALPHA));
|
||||
OUT_ACCEL_REG(R300_US_OUT_FMT_2, (R300_OUT_FMT_UNUSED |
|
||||
R300_OUT_FMT_C0_SEL_BLUE |
|
||||
R300_OUT_FMT_C1_SEL_GREEN |
|
||||
R300_OUT_FMT_C2_SEL_RED |
|
||||
R300_OUT_FMT_C3_SEL_ALPHA));
|
||||
OUT_ACCEL_REG(R300_US_OUT_FMT_3, (R300_OUT_FMT_UNUSED |
|
||||
R300_OUT_FMT_C0_SEL_BLUE |
|
||||
R300_OUT_FMT_C1_SEL_GREEN |
|
||||
R300_OUT_FMT_C2_SEL_RED |
|
||||
R300_OUT_FMT_C3_SEL_ALPHA));
|
||||
FINISH_ACCEL();
|
||||
|
||||
|
||||
BEGIN_ACCEL(3);
|
||||
OUT_ACCEL_REG(R300_FG_DEPTH_SRC, 0);
|
||||
OUT_ACCEL_REG(R300_FG_FOG_BLEND, 0);
|
||||
OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(13);
|
||||
OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
|
||||
OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZCNTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_ZTOP, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_ROPCNTL, 0);
|
||||
|
||||
OUT_ACCEL_REG(R300_RB3D_AARESOLVE_CTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_COLOR_CHANNEL_MASK, (R300_BLUE_MASK_EN |
|
||||
R300_GREEN_MASK_EN |
|
||||
R300_RED_MASK_EN |
|
||||
R300_ALPHA_MASK_EN));
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
|
||||
OUT_ACCEL_REG(R300_RB3D_CCTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_DITHER_CTL, 0);
|
||||
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5);
|
||||
if (IS_R300_3D) {
|
||||
/* clip has offset 1440 */
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
|
||||
(1088 << R300_CLIP_Y_SHIFT)));
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2920) << R300_CLIP_X_SHIFT) |
|
||||
((1080 + 2920) << R300_CLIP_Y_SHIFT)));
|
||||
} else {
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((0 << R300_CLIP_X_SHIFT) |
|
||||
(0 << R300_CLIP_Y_SHIFT)));
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_0_B, ((4080 << R300_CLIP_X_SHIFT) |
|
||||
(4080 << R300_CLIP_Y_SHIFT)));
|
||||
}
|
||||
OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
|
||||
OUT_ACCEL_REG(R300_SC_SCREENDOOR, 0xffffff);
|
||||
FINISH_ACCEL();
|
||||
} else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV280) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS300) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R200)) {
|
||||
|
||||
BEGIN_ACCEL(6);
|
||||
if (info->ChipFamily == CHIP_FAMILY_RS300) {
|
||||
OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
|
||||
} else {
|
||||
OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0);
|
||||
}
|
||||
OUT_ACCEL_REG(R200_PP_CNTL_X, 0);
|
||||
OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0);
|
||||
OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0);
|
||||
OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0);
|
||||
OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE |
|
||||
R200_VAP_VF_MAX_VTX_NUM);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
|
||||
OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
|
||||
OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
|
||||
OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
|
||||
OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
|
||||
RADEON_BFACE_SOLID |
|
||||
RADEON_FFACE_SOLID |
|
||||
RADEON_VTX_PIX_CENTER_OGL |
|
||||
RADEON_ROUND_MODE_ROUND |
|
||||
RADEON_ROUND_PREC_4TH_PIX));
|
||||
FINISH_ACCEL();
|
||||
} else {
|
||||
BEGIN_ACCEL(2);
|
||||
if ((info->ChipFamily == CHIP_FAMILY_RADEON) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV200))
|
||||
OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0);
|
||||
else
|
||||
OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
|
||||
OUT_ACCEL_REG(RADEON_SE_COORD_FMT,
|
||||
RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
|
||||
RADEON_VTX_ST0_NONPARAMETRIC |
|
||||
RADEON_VTX_ST1_NONPARAMETRIC |
|
||||
RADEON_TEX1_W_ROUTING_USE_W0);
|
||||
FINISH_ACCEL();
|
||||
|
||||
BEGIN_ACCEL(5);
|
||||
OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
|
||||
OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
|
||||
OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
|
||||
OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
|
||||
OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
|
||||
RADEON_BFACE_SOLID |
|
||||
RADEON_FFACE_SOLID |
|
||||
RADEON_VTX_PIX_CENTER_OGL |
|
||||
RADEON_ROUND_MODE_ROUND |
|
||||
RADEON_ROUND_PREC_4TH_PIX));
|
||||
FINISH_ACCEL();
|
||||
}
|
||||
safe_sti(ifl);
|
||||
FIFOWait(64);
|
||||
delay(2);
|
||||
|
||||
}
|
||||
|
||||
328
drivers/video/ati2d/init_cp.c
Normal file
328
drivers/video/ati2d/init_cp.c
Normal file
@@ -0,0 +1,328 @@
|
||||
#define RADEON_SCRATCH_REG0 0x15e0
|
||||
#define RADEON_SCRATCH_REG1 0x15e4
|
||||
#define RADEON_SCRATCH_REG2 0x15e8
|
||||
#define RADEON_SCRATCH_REG3 0x15ec
|
||||
#define RADEON_SCRATCH_REG4 0x15f0
|
||||
#define RADEON_SCRATCH_REG5 0x15f4
|
||||
#define RADEON_SCRATCH_UMSK 0x0770
|
||||
#define RADEON_SCRATCH_ADDR 0x0774
|
||||
|
||||
# define RS400_BUS_MASTER_DIS (1 << 14)
|
||||
//# define RADEON_BUS_MASTER_DIS (1 << 6)
|
||||
|
||||
#define RADEON_ISYNC_CNTL 0x1724
|
||||
# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
|
||||
# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1)
|
||||
# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2)
|
||||
# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3)
|
||||
# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
|
||||
# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
|
||||
|
||||
|
||||
void RADEONEngineFlush(RHDPtr info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->ChipFamily <= CHIP_FAMILY_RV280)
|
||||
{
|
||||
MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL,
|
||||
~RADEON_RB3D_DC_FLUSH_ALL);
|
||||
for (i = 0; i < RADEON_TIMEOUT; i++) {
|
||||
if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
|
||||
break;
|
||||
}
|
||||
if (i == RADEON_TIMEOUT) {
|
||||
dbgprintf("DC flush timeout: %x\n",
|
||||
(u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL,
|
||||
// ~R300_RB2D_DC_FLUSH_ALL);
|
||||
// for (i = 0; i < RADEON_TIMEOUT; i++) {
|
||||
// if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
|
||||
// break;
|
||||
// }
|
||||
// if (i == RADEON_TIMEOUT) {
|
||||
// dbgprintf("DC flush timeout: %x\n",
|
||||
// (u32_t)INREG(R300_DSTCACHE_CTLSTAT));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int radeon_do_wait_for_idle()
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
ret = R5xxFIFOWaitLocal(64);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < RADEON_TIMEOUT; i++)
|
||||
{
|
||||
if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
|
||||
RADEONEngineFlush(&rhd);
|
||||
return 0;
|
||||
}
|
||||
usleep(1);
|
||||
}
|
||||
dbgprintf("wait idle failed status : 0x%08X 0x%08X\n",
|
||||
INREG(RADEON_RBBM_STATUS),
|
||||
INREG(R300_VAP_CNTL_STATUS));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* CP control, initialization
|
||||
*/
|
||||
|
||||
/* Load the microcode for the CP */
|
||||
|
||||
#include "radeon_microcode.h"
|
||||
|
||||
static void load_microcode(RHDPtr info)
|
||||
{
|
||||
int i;
|
||||
const u32_t (*microcode)[2];
|
||||
|
||||
OUTREG(RADEON_CP_ME_RAM_ADDR, 0);
|
||||
|
||||
if ( (info->ChipFamily == CHIP_FAMILY_LEGACY ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RADEON ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV100 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV200 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS100 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS200 ))
|
||||
{
|
||||
microcode = R100_cp_microcode;
|
||||
dbgprintf("Loading R100 Microcode\n");
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R200 ) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV250) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV280) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS300))
|
||||
{
|
||||
microcode = R200_cp_microcode;
|
||||
dbgprintf("Loading R200 Microcode\n");
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R350) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV350) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV380) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS400) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS480))
|
||||
{
|
||||
dbgprintf("Loading R300 Microcode\n");
|
||||
microcode = R300_cp_microcode;
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_R420) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV410))
|
||||
{
|
||||
dbgprintf("Loading R400 Microcode\n");
|
||||
microcode = R420_cp_microcode;
|
||||
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740))
|
||||
{
|
||||
dbgprintf("Loading RS690/RS740 Microcode\n");
|
||||
microcode = RS690_cp_microcode;
|
||||
}
|
||||
else if ((info->ChipFamily == CHIP_FAMILY_RV515) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R520) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV530) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_R580) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV560) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RV570))
|
||||
{
|
||||
dbgprintf("Loading R500 Microcode\n");
|
||||
microcode = R520_cp_microcode;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]);
|
||||
OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_ring_buffer(RHDPtr info)
|
||||
{
|
||||
u32_t ring_base;
|
||||
u32_t tmp;
|
||||
|
||||
info->ringBase = CreateRingBuffer( 64*1024, PG_SW);
|
||||
|
||||
dbgprintf("create cp ring buffer %x\n", rhd.ringBase);
|
||||
ring_base = GetPgAddr(rhd.ringBase);
|
||||
dbgprintf("ring base %x\n", ring_base);
|
||||
|
||||
OUTREG(RADEON_CP_RB_BASE, ring_base);
|
||||
|
||||
info->ring_avail = 64*1024/4 ;
|
||||
|
||||
/* Set the write pointer delay */
|
||||
OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
|
||||
rhd.host_rp = rhd.ring_rp;
|
||||
|
||||
OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
|
||||
|
||||
tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp);
|
||||
|
||||
OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer
|
||||
|
||||
/* Set ring buffer size */
|
||||
OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13);
|
||||
|
||||
/* Initialize the scratch register pointer. This will cause
|
||||
* the scratch register values to be written out to memory
|
||||
* whenever they are updated.
|
||||
*
|
||||
* We simply put this behind the ring read pointer, this works
|
||||
* with PCI GART as well as (whatever kind of) AGP GART
|
||||
*/
|
||||
|
||||
tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0);
|
||||
OUTREG(RADEON_SCRATCH_ADDR, tmp);
|
||||
|
||||
OUTREG(RADEON_SCRATCH_UMSK, 0x0);
|
||||
//OUTREG(0x778, 1);
|
||||
|
||||
/* Turn on bus mastering */
|
||||
if ( (info->ChipFamily == CHIP_FAMILY_RS400) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS690) ||
|
||||
(info->ChipFamily == CHIP_FAMILY_RS740) )
|
||||
{
|
||||
/* rs400, rs690/rs740 */
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
}
|
||||
else if (!((info->ChipFamily == CHIP_FAMILY_RV380) ||
|
||||
(info->ChipFamily >= CHIP_FAMILY_R420)))
|
||||
{
|
||||
/* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
} /* PCIE cards appears to not need this */
|
||||
|
||||
tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
|
||||
OUTREG(RADEON_BUS_CNTL, tmp);
|
||||
|
||||
radeon_do_wait_for_idle();
|
||||
|
||||
/* Sync everything up */
|
||||
OUTREG(RADEON_ISYNC_CNTL,
|
||||
(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define RADEON_WAIT_UNTIL_IDLE() do { \
|
||||
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) ); \
|
||||
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
|
||||
RADEON_WAIT_3D_IDLECLEAN | \
|
||||
RADEON_WAIT_HOST_IDLECLEAN) ); \
|
||||
} while (0)
|
||||
|
||||
#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
|
||||
# define RADEON_RB3D_ZC_FLUSH (1 << 0)
|
||||
# define RADEON_RB3D_ZC_FREE (1 << 2)
|
||||
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
|
||||
# define RADEON_RB3D_ZC_BUSY (1 << 31)
|
||||
# define R300_ZC_FLUSH (1 << 0)
|
||||
# define R300_ZC_FREE (1 << 1)
|
||||
# define R300_ZC_BUSY (1 << 31)
|
||||
# define RADEON_RB3D_DC_FLUSH (3 << 0)
|
||||
# define RADEON_RB3D_DC_FREE (3 << 2)
|
||||
# define RADEON_RB3D_DC_FLUSH_ALL 0xf
|
||||
# define RADEON_RB3D_DC_BUSY (1 << 31)
|
||||
# define R300_RB3D_DC_FLUSH (2 << 0)
|
||||
# define R300_RB3D_DC_FREE (2 << 2)
|
||||
#
|
||||
#define RADEON_PURGE_CACHE() do { \
|
||||
if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \
|
||||
} else { \
|
||||
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_FLUSH_ZCACHE() do { \
|
||||
if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \
|
||||
OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
|
||||
} else { \
|
||||
OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) ); \
|
||||
OUT_RING( R300_ZC_FLUSH ); \
|
||||
} \
|
||||
} while (0)
|
||||
#define RADEON_PURGE_ZCACHE() do { \
|
||||
if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
|
||||
OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \
|
||||
} else { \
|
||||
OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1)); \
|
||||
OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int radeon_cp_start(RHDPtr info)
|
||||
{
|
||||
u32_t *ring, write;
|
||||
u32_t ifl;
|
||||
radeon_do_wait_for_idle(64);
|
||||
|
||||
OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
|
||||
|
||||
ifl = safe_cli();
|
||||
|
||||
BEGIN_RING(8);
|
||||
/* isync can only be written through cp on r5xx write it here */
|
||||
OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1));
|
||||
OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
|
||||
RADEON_ISYNC_ANY3D_IDLE2D |
|
||||
RADEON_ISYNC_WAIT_IDLEGUI |
|
||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI);
|
||||
RADEON_PURGE_CACHE();
|
||||
RADEON_PURGE_ZCACHE();
|
||||
RADEON_WAIT_UNTIL_IDLE();
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
safe_sti(ifl);
|
||||
|
||||
radeon_do_wait_for_idle();
|
||||
};
|
||||
|
||||
|
||||
Bool init_cp(RHDPtr info)
|
||||
{
|
||||
load_microcode(&rhd);
|
||||
|
||||
init_ring_buffer(&rhd);
|
||||
|
||||
radeon_engine_reset(&rhd);
|
||||
|
||||
rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
|
||||
OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp);
|
||||
|
||||
radeon_cp_start(&rhd);
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
|
||||
56
drivers/video/ati2d/makefile
Normal file
56
drivers/video/ati2d/makefile
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDRHD = -shared -T ld.x -s --file-alignment 32
|
||||
|
||||
INCLUDES = -I ../../include
|
||||
|
||||
HFILES:= ../../include/types.h \
|
||||
../../include/syscall.h \
|
||||
../../include/pci.h \
|
||||
atihw.h \
|
||||
accel_2d.h \
|
||||
r5xx_regs.h \
|
||||
radeon_microcode.h
|
||||
|
||||
SRC_DEP:= init.c \
|
||||
pci.c \
|
||||
ati_mem.c \
|
||||
init_cp.c \
|
||||
init_3d.inc \
|
||||
blend.inc \
|
||||
r500.inc \
|
||||
pixmap.inc \
|
||||
accel_2d.inc
|
||||
|
||||
ATI_SRC:= ati2d.c
|
||||
|
||||
ATI_OBJ:= ati2d.obj
|
||||
|
||||
|
||||
ATI_OBJ = $(patsubst %.s, %.obj, $(patsubst %.asm, %.obj,\
|
||||
$(patsubst %.c, %.obj, $(ATI_SRC))))
|
||||
|
||||
|
||||
ATI2D = ati2d.dll
|
||||
|
||||
all: $(ATI2D)
|
||||
|
||||
$(ATI2D): $(ATI_OBJ) $(SRC_DEP) $(HFILES) Makefile
|
||||
wlink name ati2d.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @ati2d.lk
|
||||
kpack.exe ati2d.dll ati2d.drv
|
||||
|
||||
ati2d.obj : ati2d.c $(SRC_DEP) $(HFILES) Makefile
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -o ati2d.obj ati2d.c
|
||||
|
||||
curhelp.obj : curhelp.asm
|
||||
$(FASM) curhelp.asm
|
||||
|
||||
%.obj : %.c $(HFILES)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
%.obj: %.asm
|
||||
as -o $@ $<
|
||||
|
||||
|
||||
288
drivers/video/ati2d/pci.c
Normal file
288
drivers/video/ati2d/pci.c
Normal file
@@ -0,0 +1,288 @@
|
||||
|
||||
#include "ati_pciids_gen.h"
|
||||
#include "radeon_chipset_gen.h"
|
||||
#include "radeon_chipinfo_gen.h"
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
xf86TokenToString(SymTabPtr table, int token)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; table[i].token >= 0 && table[i].token != token; i++){};
|
||||
|
||||
if (table[i].token < 0)
|
||||
return NULL;
|
||||
else
|
||||
return(table[i].name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const RADEONCardInfo *RadeonDevMatch(u16_t dev,const RADEONCardInfo *list)
|
||||
{
|
||||
while(list->pci_device_id)
|
||||
{
|
||||
if(dev == list->pci_device_id)
|
||||
return list;
|
||||
list++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RHDPtr FindPciDevice()
|
||||
{
|
||||
const RADEONCardInfo *dev;
|
||||
u32_t bus, last_bus;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return 0;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
u32_t id;
|
||||
id = PciRead32(bus,devfn, 0);
|
||||
|
||||
if( (u16_t)id != VENDOR_ATI)
|
||||
continue;
|
||||
|
||||
rhd.PciDeviceID = (id>>16);
|
||||
|
||||
if( (dev = RadeonDevMatch(rhd.PciDeviceID, RADEONCards))!=NULL)
|
||||
{
|
||||
u32_t reg2C;
|
||||
int i;
|
||||
|
||||
rhd.chipset = (char*)xf86TokenToString(RADEONChipsets, rhd.PciDeviceID);
|
||||
if (!rhd.chipset){
|
||||
dbgprintf("ChipID 0x%04x is not recognized\n", rhd.PciDeviceID);
|
||||
return FALSE;
|
||||
}
|
||||
dbgprintf("Chipset: \"%s\" (ChipID = 0x%04x)\n",
|
||||
rhd.chipset,rhd.PciDeviceID);
|
||||
|
||||
rhd.bus = bus;
|
||||
rhd.devfn = devfn;
|
||||
rhd.PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
|
||||
rhd.ChipFamily = dev->chip_family;
|
||||
rhd.IsMobility = dev->mobility;
|
||||
rhd.IsIGP = dev->igp;
|
||||
rhd.HasCRTC2 = !dev->nocrtc2;
|
||||
|
||||
reg2C = PciRead32(bus,devfn, 0x2C);
|
||||
|
||||
rhd.subvendor_id = reg2C & 0xFFFF;;
|
||||
rhd.subdevice_id = reg2C >> 16;
|
||||
|
||||
if (rhd.ChipFamily >= CHIP_FAMILY_R600)
|
||||
dbgprintf("R600 unsupported yet.\nExit\n");
|
||||
|
||||
if( rhd.ChipFamily >= CHIP_FAMILY_R420)
|
||||
rhd.gart_type = RADEON_IS_PCIE;
|
||||
else
|
||||
rhd.gart_type = RADEON_IS_PCI;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
u32_t base;
|
||||
Bool validSize;
|
||||
|
||||
base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
|
||||
if(base)
|
||||
{
|
||||
if (base & PCI_MAP_IO){
|
||||
rhd.ioBase[i] = (u32_t)PCIGETIO(base);
|
||||
rhd.memtype[i] = base & PCI_MAP_IO_ATTR_MASK;
|
||||
}
|
||||
else{
|
||||
rhd.memBase[i] = (u32_t)PCIGETMEMORY(base);
|
||||
rhd.memtype[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
|
||||
}
|
||||
}
|
||||
rhd.memsize[i] = pciGetBaseSize(bus,devfn, i, TRUE, &validSize);
|
||||
}
|
||||
return &rhd;
|
||||
}
|
||||
}
|
||||
};
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min)
|
||||
{
|
||||
int offset;
|
||||
u32_t addr1;
|
||||
u32_t addr2;
|
||||
u32_t mask1;
|
||||
u32_t mask2;
|
||||
int bits = 0;
|
||||
|
||||
/*
|
||||
* silently ignore bogus index values. Valid values are 0-6. 0-5 are
|
||||
* the 6 base address registers, and 6 is the ROM base address register.
|
||||
*/
|
||||
if (index < 0 || index > 6)
|
||||
return 0;
|
||||
|
||||
if (min)
|
||||
*min = destructive;
|
||||
|
||||
/* Get the PCI offset */
|
||||
if (index == 6)
|
||||
offset = PCI_MAP_ROM_REG;
|
||||
else
|
||||
offset = PCI_MAP_REG_START + (index << 2);
|
||||
|
||||
addr1 = PciRead32(bus, devfn, offset);
|
||||
/*
|
||||
* Check if this is the second part of a 64 bit address.
|
||||
* XXX need to check how endianness affects 64 bit addresses.
|
||||
*/
|
||||
if (index > 0 && index < 6) {
|
||||
addr2 = PciRead32(bus, devfn, offset - 4);
|
||||
if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (destructive) {
|
||||
PciWrite32(bus, devfn, offset, 0xffffffff);
|
||||
mask1 = PciRead32(bus, devfn, offset);
|
||||
PciWrite32(bus, devfn, offset, addr1);
|
||||
} else {
|
||||
mask1 = addr1;
|
||||
}
|
||||
|
||||
/* Check if this is the first part of a 64 bit address. */
|
||||
if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
|
||||
{
|
||||
if (PCIGETMEMORY(mask1) == 0)
|
||||
{
|
||||
addr2 = PciRead32(bus, devfn, offset + 4);
|
||||
if (destructive)
|
||||
{
|
||||
PciWrite32(bus, devfn, offset + 4, 0xffffffff);
|
||||
mask2 = PciRead32(bus, devfn, offset + 4);
|
||||
PciWrite32(bus, devfn, offset + 4, addr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
mask2 = addr2;
|
||||
}
|
||||
if (mask2 == 0)
|
||||
return 0;
|
||||
bits = 32;
|
||||
while ((mask2 & 1) == 0)
|
||||
{
|
||||
bits++;
|
||||
mask2 >>= 1;
|
||||
}
|
||||
if (bits > 32)
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
if (index < 6)
|
||||
if (PCI_MAP_IS_MEM(mask1))
|
||||
mask1 = PCIGETMEMORY(mask1);
|
||||
else
|
||||
mask1 = PCIGETIO(mask1);
|
||||
else
|
||||
mask1 = PCIGETROM(mask1);
|
||||
if (mask1 == 0)
|
||||
return 0;
|
||||
bits = 0;
|
||||
while ((mask1 & 1) == 0) {
|
||||
bits++;
|
||||
mask1 >>= 1;
|
||||
}
|
||||
/* I/O maps can be no larger than 8 bits */
|
||||
|
||||
if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
|
||||
bits = 8;
|
||||
/* ROM maps can be no larger than 24 bits */
|
||||
if (index == 6 && bits > 24)
|
||||
bits = 24;
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define PCI_FIND_CAP_TTL 48
|
||||
|
||||
static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos,
|
||||
int cap, int *ttl)
|
||||
{
|
||||
u8_t id;
|
||||
|
||||
while ((*ttl)--)
|
||||
{
|
||||
pos = pciReadByte(pciTag, pos);
|
||||
if (pos < 0x40)
|
||||
break;
|
||||
pos &= ~3;
|
||||
id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID);
|
||||
if (id == 0xff)
|
||||
break;
|
||||
if (id == cap)
|
||||
return pos;
|
||||
pos += PCI_CAP_LIST_NEXT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap)
|
||||
{
|
||||
int ttl = PCI_FIND_CAP_TTL;
|
||||
|
||||
return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl);
|
||||
}
|
||||
|
||||
static int __pci_bus_find_cap_start(PCITAG pciTag)
|
||||
{
|
||||
u16_t status;
|
||||
u8_t hdr_type;
|
||||
|
||||
status = pciReadWord(pciTag, PCI_STATUS);
|
||||
if (!(status & PCI_STATUS_CAP_LIST))
|
||||
return 0;
|
||||
|
||||
hdr_type = pciReadByte(pciTag, 0x0E);
|
||||
switch (hdr_type)
|
||||
{
|
||||
case PCI_HEADER_TYPE_NORMAL:
|
||||
case PCI_HEADER_TYPE_BRIDGE:
|
||||
return PCI_CAPABILITY_LIST;
|
||||
case PCI_HEADER_TYPE_CARDBUS:
|
||||
return PCI_CB_CAPABILITY_LIST;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pci_find_capability(PCITAG pciTag, int cap)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = __pci_bus_find_cap_start(pciTag);
|
||||
if (pos)
|
||||
pos = __pci_find_next_cap(pciTag, pos, cap);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ int drm_device_is_pcie(PCITAG pciTag)
|
||||
{
|
||||
return pci_find_capability(pciTag, PCI_CAP_ID_EXP);
|
||||
}
|
||||
|
||||
258
drivers/video/ati2d/pixmap.inc
Normal file
258
drivers/video/ati2d/pixmap.inc
Normal file
@@ -0,0 +1,258 @@
|
||||
|
||||
int CreatePixmap(pixmap_t *io)
|
||||
{
|
||||
local_pixmap_t *pixmap;
|
||||
|
||||
unsigned pitch;
|
||||
size_t size;
|
||||
|
||||
addr_t mem_local = 0;
|
||||
addr_t mem_dma = 0;
|
||||
void *mapped;
|
||||
|
||||
if( (io->width == 0) || (io->width > 2048)||
|
||||
(io->height == 0)|| (io->height > 2048))
|
||||
{
|
||||
dbgprintf("Invalid pixmap size w:%d h:%d\n", io->width,io->height);
|
||||
return ERR_PARAM;
|
||||
};
|
||||
|
||||
pixmap = malloc(sizeof(local_pixmap_t));
|
||||
|
||||
if(!pixmap)
|
||||
return ERR_PARAM;
|
||||
|
||||
pitch = ((io->width+15)&~15)*4;
|
||||
size = pitch*io->height;
|
||||
|
||||
dbgprintf("pitch = %d\n", pitch);
|
||||
|
||||
if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL ) {
|
||||
mem_local = rhd_mem_alloc(&rhd,RHD_MEM_FB,size);
|
||||
mem_dma = mem_local + rhd.fbLocation;
|
||||
}
|
||||
else
|
||||
mem_local = mem_dma = AllocPages( size >> 12 );
|
||||
|
||||
if ( !mem_local) {
|
||||
dbgprintf("Not enough memory for pixmap\n");
|
||||
free(pixmap);
|
||||
return ERR_PARAM;
|
||||
};
|
||||
|
||||
pixmap->pitch_offset = ((pitch/64)<<22)| (mem_dma>>10);
|
||||
pixmap->local = mem_dma;
|
||||
|
||||
size = (size+4095) & ~ 4095;
|
||||
|
||||
if (mapped = UserAlloc(size))
|
||||
{
|
||||
CommitPages(mapped, mem_dma|7|(1<<9), size);
|
||||
|
||||
io->mapped = mapped;
|
||||
io->pitch = pitch;
|
||||
io->handle = (u32_t)pixmap;
|
||||
|
||||
pixmap->width = io->width;
|
||||
pixmap->height = io->height;
|
||||
pixmap->format = PICT_a8r8g8b8;
|
||||
pixmap->flags = io->flags;
|
||||
pixmap->pitch = pitch;
|
||||
pixmap->mapped = mapped;
|
||||
|
||||
dbgprintf("pixmap.pitch_offset: %x\n", pixmap->pitch_offset);
|
||||
dbgprintf("width: %d height: %d\n",pixmap->width,pixmap->height );
|
||||
dbgprintf("map at %x\n", pixmap->mapped);
|
||||
|
||||
return ERR_OK;
|
||||
};
|
||||
rhd_mem_free(&rhd, RHD_MEM_FB, mem_local);
|
||||
free(pixmap);
|
||||
|
||||
return ERR_PARAM;
|
||||
};
|
||||
|
||||
|
||||
int DestroyPixmap( pixmap_t *io )
|
||||
{
|
||||
local_pixmap_t *pixmap;
|
||||
size_t size;
|
||||
|
||||
dbgprintf("Destroy pixmap %x\n", io->handle);
|
||||
|
||||
if(io->handle == -1)
|
||||
return ERR_PARAM;
|
||||
else
|
||||
pixmap = (local_pixmap_t*)io->handle;
|
||||
|
||||
size = (pixmap->pitch*pixmap->height+4095) & ~ 4095;
|
||||
|
||||
UnmapPages(pixmap->mapped, size);
|
||||
UserFree(pixmap->mapped);
|
||||
|
||||
if( (io->flags & PX_MEM_MASK) == PX_MEM_LOCAL )
|
||||
{
|
||||
rhd_mem_free(&rhd,RHD_MEM_FB,pixmap->local-rhd.fbLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
count_t pages = size >> 12;
|
||||
addr_t base = pixmap->local;
|
||||
|
||||
while( pages--)
|
||||
{
|
||||
addr_t tmp;
|
||||
// __asm__ __volatile__(
|
||||
// "call *__imp__PageFree"
|
||||
// :"=eax" (tmp):"a" (base) );
|
||||
// base+= 4096;
|
||||
};
|
||||
}
|
||||
|
||||
free(pixmap);
|
||||
|
||||
io->format = 0;
|
||||
io->pitch = 0;
|
||||
io->mapped = NULL;
|
||||
io->handle = 0;
|
||||
|
||||
return ERR_OK;
|
||||
};
|
||||
|
||||
|
||||
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
|
||||
# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
|
||||
|
||||
#define ATI_PCIE_WRITE 0x4
|
||||
#define ATI_PCIE_READ 0x8
|
||||
|
||||
#define upper_32_bits(n) ((u32_t)(((n) >> 16) >> 16))
|
||||
|
||||
|
||||
static void bind_pcie(u32_t *gart, addr_t base, count_t pages)
|
||||
{
|
||||
addr_t page_base;
|
||||
|
||||
while(pages--)
|
||||
{
|
||||
page_base = base & ATI_PCIGART_PAGE_MASK;
|
||||
|
||||
page_base >>= 8;
|
||||
page_base |= (upper_32_bits(base) & 0xff) << 24;
|
||||
page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
|
||||
|
||||
*gart = page_base;
|
||||
base+= 4096;
|
||||
gart++;
|
||||
}
|
||||
__asm__ __volatile("sfence":::"memory");
|
||||
|
||||
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
|
||||
RADEON_PCIE_TX_GART_EN
|
||||
| RADEON_PCIE_TX_GART_INVALIDATE_TLB);
|
||||
}
|
||||
|
||||
static void bind_pci(u32_t *gart, addr_t base, count_t pages)
|
||||
{
|
||||
u32_t tmp;
|
||||
|
||||
tmp = INREG(RADEON_AIC_CNTL);
|
||||
OUTREG(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN);
|
||||
|
||||
while(pages--)
|
||||
{
|
||||
*gart = base & ATI_PCIGART_PAGE_MASK;
|
||||
base+= 4096;
|
||||
gart++;
|
||||
}
|
||||
__asm__ __volatile("sfence":::"memory");
|
||||
|
||||
OUTREG(RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN);
|
||||
OUTREG(RADEON_AIC_PT_BASE, rhd.gart_table_dma);
|
||||
}
|
||||
|
||||
static addr_t bind_pixmap(local_pixmap_t *pixmap)
|
||||
{
|
||||
u32_t *gart = rhd.gart_table;
|
||||
count_t pages = ((pixmap->height * pixmap->pitch+4095)&~4095)>>12;
|
||||
addr_t base = pixmap->local;
|
||||
|
||||
if( rhd.gart_type == RADEON_IS_PCIE)
|
||||
bind_pcie(gart, base, pages);
|
||||
else
|
||||
bind_pci(gart, base, pages);
|
||||
|
||||
return ((pixmap->pitch / 64) << 22) | (rhd.gart_vm_start >> 10);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int LockPixmap(userpixmap_t *io)
|
||||
{
|
||||
pixmap_t *pixmap;
|
||||
size_t size;
|
||||
void *usermap;
|
||||
|
||||
dbgprintf("Lock pixmap %x\n", io->pixmap);
|
||||
|
||||
if(io->pixmap == (pixmap_t*)-1)
|
||||
return ERR_PARAM;
|
||||
else
|
||||
pixmap = io->pixmap;
|
||||
|
||||
if( (pixmap->flags & 1) == PX_LOCK )
|
||||
return ERR_PARAM;
|
||||
|
||||
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
|
||||
if (usermap = UserAlloc(size))
|
||||
{
|
||||
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
|
||||
pixmap->flags |= PX_LOCK;
|
||||
pixmap->usermap = usermap;
|
||||
io->usermap = usermap;
|
||||
io->pitch = pixmap->pitch;
|
||||
dbgprintf("map at %x\n", io->usermap);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
else
|
||||
return ERR_PARAM;
|
||||
};
|
||||
|
||||
int UnlockPixmap(userpixmap_t *io)
|
||||
{
|
||||
pixmap_t *pixmap;
|
||||
size_t size;
|
||||
|
||||
dbgprintf("Unlock pixmap %x\n", io->pixmap);
|
||||
|
||||
if(io->pixmap == (pixmap_t*)-1)
|
||||
return ERR_PARAM;
|
||||
else
|
||||
pixmap = io->pixmap;
|
||||
|
||||
if( (pixmap->flags & 1) != PX_LOCK )
|
||||
return ERR_PARAM;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
if( (pixmap->usermap == 0)||
|
||||
((u32_t)pixmap->usermap >= 0x80000000) ||
|
||||
((u32_t)pixmap->usermap & 4095)
|
||||
)
|
||||
return ERR_PARAM;
|
||||
|
||||
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
|
||||
|
||||
UnmapPages(pixmap->usermap, size);
|
||||
UserFree(pixmap->usermap);
|
||||
pixmap->usermap = NULL;
|
||||
pixmap->flags &= ~PX_LOCK;
|
||||
io->usermap = NULL;
|
||||
io->pitch = 0;
|
||||
|
||||
return ERR_OK;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
273
drivers/video/ati2d/r500.inc
Normal file
273
drivers/video/ati2d/r500.inc
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
#define R300_TEST
|
||||
|
||||
#include "r5xx_regs.h"
|
||||
|
||||
|
||||
#define R5XX_LOOP_COUNT 2000000
|
||||
|
||||
#define RADEON_CLOCK_CNTL_DATA 0x000c
|
||||
|
||||
#define RADEON_CLOCK_CNTL_INDEX 0x0008
|
||||
# define RADEON_PLL_WR_EN (1 << 7)
|
||||
# define RADEON_PLL_DIV_SEL (3 << 8)
|
||||
# define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8)
|
||||
|
||||
#define RADEON_MCLK_CNTL 0x0012 /* PLL */
|
||||
# define RADEON_FORCEON_MCLKA (1 << 16)
|
||||
# define RADEON_FORCEON_MCLKB (1 << 17)
|
||||
# define RADEON_FORCEON_YCLKA (1 << 18)
|
||||
# define RADEON_FORCEON_YCLKB (1 << 19)
|
||||
# define RADEON_FORCEON_MC (1 << 20)
|
||||
# define RADEON_FORCEON_AIC (1 << 21)
|
||||
# define R300_DISABLE_MC_MCLKA (1 << 21)
|
||||
# define R300_DISABLE_MC_MCLKB (1 << 21)
|
||||
|
||||
void radeon_engine_reset(RHDPtr info)
|
||||
{
|
||||
u32_t clock_cntl_index;
|
||||
u32_t mclk_cntl;
|
||||
u32_t rbbm_soft_reset;
|
||||
u32_t host_path_cntl;
|
||||
|
||||
if (info->ChipFamily <= CHIP_FAMILY_RV410)
|
||||
{
|
||||
/* may need something similar for newer chips */
|
||||
clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
|
||||
mclk_cntl = INPLL( RADEON_MCLK_CNTL);
|
||||
|
||||
OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
|
||||
RADEON_FORCEON_MCLKA |
|
||||
RADEON_FORCEON_MCLKB |
|
||||
RADEON_FORCEON_YCLKA |
|
||||
RADEON_FORCEON_YCLKB |
|
||||
RADEON_FORCEON_MC |
|
||||
RADEON_FORCEON_AIC));
|
||||
}
|
||||
|
||||
rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
|
||||
|
||||
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
|
||||
RADEON_SOFT_RESET_CP |
|
||||
RADEON_SOFT_RESET_HI |
|
||||
RADEON_SOFT_RESET_SE |
|
||||
RADEON_SOFT_RESET_RE |
|
||||
RADEON_SOFT_RESET_PP |
|
||||
RADEON_SOFT_RESET_E2 |
|
||||
RADEON_SOFT_RESET_RB));
|
||||
INREG(RADEON_RBBM_SOFT_RESET);
|
||||
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
|
||||
~(RADEON_SOFT_RESET_CP |
|
||||
RADEON_SOFT_RESET_HI |
|
||||
RADEON_SOFT_RESET_SE |
|
||||
RADEON_SOFT_RESET_RE |
|
||||
RADEON_SOFT_RESET_PP |
|
||||
RADEON_SOFT_RESET_E2 |
|
||||
RADEON_SOFT_RESET_RB)));
|
||||
INREG(RADEON_RBBM_SOFT_RESET);
|
||||
|
||||
if (info->ChipFamily <= CHIP_FAMILY_RV410) {
|
||||
OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
|
||||
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
|
||||
OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
|
||||
}
|
||||
};
|
||||
|
||||
static Bool R5xxFIFOWaitLocal(u32_t required) //R100-R500
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RADEON_TIMEOUT; i++)
|
||||
if (required <= (INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK))
|
||||
return TRUE;
|
||||
|
||||
dbgprintf("%s: Timeout 0x%08X.\n", __func__, (u32_t) INREG(RADEON_RBBM_STATUS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void FIFOWait(u32_t required)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 200; i++)
|
||||
{
|
||||
if (required <= (INREG(RADEON_RBBM_STATUS) &
|
||||
RADEON_RBBM_FIFOCNT_MASK))
|
||||
return ;
|
||||
delay(2);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Flush all dirty data in the Pixel Cache to memory.
|
||||
*/
|
||||
|
||||
static Bool
|
||||
R5xx2DFlush()
|
||||
{
|
||||
int i;
|
||||
|
||||
MASKREG(R5XX_DSTCACHE_CTLSTAT,
|
||||
R5XX_DSTCACHE_FLUSH_ALL, R5XX_DSTCACHE_FLUSH_ALL);
|
||||
|
||||
for (i = 0; i < R5XX_LOOP_COUNT; i++)
|
||||
if (!(INREG(R5XX_DSTCACHE_CTLSTAT) & R5XX_DSTCACHE_BUSY))
|
||||
return TRUE;
|
||||
|
||||
dbgprintf("%s: Timeout 0x%08x.\n", __func__,
|
||||
(unsigned int)INREG(R5XX_DSTCACHE_CTLSTAT));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
R5xx2DIdleLocal() //R100-R500
|
||||
{
|
||||
int i;
|
||||
|
||||
/* wait for fifo to clear */
|
||||
for (i = 0; i < R5XX_LOOP_COUNT; i++)
|
||||
if (64 == (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
|
||||
break;
|
||||
|
||||
if (i == R5XX_LOOP_COUNT) {
|
||||
dbgprintf("%s: FIFO Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* wait for engine to go idle */
|
||||
for (i = 0; i < R5XX_LOOP_COUNT; i++) {
|
||||
if (!(INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_ACTIVE)) {
|
||||
R5xx2DFlush();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
dbgprintf("%s: Idle Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R5xx2DSetup()
|
||||
{
|
||||
|
||||
/* Setup engine location. This shouldn't be necessary since we
|
||||
* set them appropriately before any accel ops, but let's avoid
|
||||
* random bogus DMA in case we inadvertently trigger the engine
|
||||
* in the wrong place (happened). */
|
||||
R5xxFIFOWaitLocal(2);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
|
||||
R5xxFIFOWaitLocal(1);
|
||||
MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
|
||||
|
||||
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
|
||||
|
||||
R5xxFIFOWaitLocal(3);
|
||||
OUTREG(R5XX_SC_TOP_LEFT, 0);
|
||||
OUTREG(R5XX_SC_BOTTOM_RIGHT,
|
||||
RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX);
|
||||
OUTREG(R5XX_DEFAULT_SC_BOTTOM_RIGHT,
|
||||
RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX);
|
||||
|
||||
R5xxFIFOWaitLocal(1);
|
||||
// OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control |
|
||||
// R5XX_GMC_BRUSH_SOLID_COLOR | R5XX_GMC_SRC_DATATYPE_COLOR);
|
||||
OUTREG(R5XX_DP_CNTL, R5XX_DST_X_LEFT_TO_RIGHT | R5XX_DST_Y_TOP_TO_BOTTOM);
|
||||
|
||||
R5xxFIFOWaitLocal(5);
|
||||
OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF);
|
||||
OUTREG(R5XX_DP_BRUSH_BKGD_CLR, 0x00000000);
|
||||
OUTREG(R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF);
|
||||
OUTREG(R5XX_DP_SRC_BKGD_CLR, 0x00000000);
|
||||
OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF);
|
||||
|
||||
R5xx2DIdleLocal();
|
||||
}
|
||||
|
||||
void R5xxFIFOWait(u32_t required)
|
||||
{
|
||||
if (!R5xxFIFOWaitLocal(required)) {
|
||||
radeon_engine_reset(&rhd);
|
||||
R5xx2DSetup();
|
||||
}
|
||||
}
|
||||
|
||||
void R5xx2DIdle()
|
||||
{
|
||||
if (!R5xx2DIdleLocal()) {
|
||||
// R5xx2DReset();
|
||||
R5xx2DSetup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void R5xx2DInit()
|
||||
{
|
||||
u32_t base;
|
||||
int screensize;
|
||||
int screenpitch;
|
||||
|
||||
screensize = GetScreenSize();
|
||||
screenpitch = GetScreenPitch();
|
||||
|
||||
rhd.displayWidth = screensize >> 16;
|
||||
rhd.displayHeight = screensize & 0xFFFF;
|
||||
|
||||
rhd.__xmin = 0;
|
||||
rhd.__ymin = 0;
|
||||
rhd.__xmax = rhd.displayWidth - 1;
|
||||
rhd.__ymax = rhd.displayHeight - 1;
|
||||
|
||||
clip.xmin = 0;
|
||||
clip.ymin = 0;
|
||||
clip.xmax = rhd.displayWidth - 1;
|
||||
clip.ymax = rhd.displayHeight - 1;
|
||||
|
||||
dbgprintf("screen width %d height %d\n",
|
||||
rhd.displayWidth, rhd.displayHeight);
|
||||
|
||||
rhd.gui_control = ((6 << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||
| RADEON_GMC_CLR_CMP_CNTL_DIS
|
||||
| RADEON_GMC_DST_PITCH_OFFSET_CNTL);
|
||||
|
||||
dbgprintf("gui_control %x \n", rhd.gui_control);
|
||||
|
||||
rhd.surface_cntl = 0;
|
||||
|
||||
rhd.dst_pitch_offset = (((rhd.displayWidth * 4 / 64)<< 22) |
|
||||
(rhd.fbLocation >> 10));
|
||||
|
||||
|
||||
dbgprintf("dst_pitch_offset %x \n", rhd.dst_pitch_offset);
|
||||
|
||||
scr_pixmap.width = rhd.displayWidth;
|
||||
scr_pixmap.height = rhd.displayHeight;
|
||||
scr_pixmap.format = PICT_a8r8g8b8;
|
||||
scr_pixmap.flags = PX_MEM_LOCAL;
|
||||
scr_pixmap.pitch = rhd.displayWidth * 4 ;//screenpitch;
|
||||
scr_pixmap.local = rhd.fbLocation;
|
||||
scr_pixmap.pitch_offset = rhd.dst_pitch_offset;
|
||||
scr_pixmap.mapped = 0;
|
||||
|
||||
R5xxFIFOWaitLocal(2);
|
||||
OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset);
|
||||
|
||||
R5xxFIFOWaitLocal(1);
|
||||
MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
|
||||
|
||||
OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
|
||||
|
||||
#if !R300_PIO
|
||||
|
||||
init_cp(&rhd);
|
||||
|
||||
#endif
|
||||
|
||||
R5xx2DSetup();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
288
drivers/video/ati2d/r5xx_2dregs.h
Normal file
288
drivers/video/ati2d/r5xx_2dregs.h
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 on 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 (including the
|
||||
* next paragraph) 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
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
||||
* THEIR SUPPLIERS 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.
|
||||
*/
|
||||
/* WARNING: the above is not a standard MIT license. */
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@xfree86.org>
|
||||
* Rickard E. Faith <faith@valinux.com>
|
||||
* Alan Hourihane <alanh@fairlite.demon.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef _R5XX_2DREGS_H
|
||||
# define _R5XX_2DREGS_H
|
||||
|
||||
#define R5XX_DATATYPE_VQ 0
|
||||
#define R5XX_DATATYPE_CI4 1
|
||||
#define R5XX_DATATYPE_CI8 2
|
||||
#define R5XX_DATATYPE_ARGB1555 3
|
||||
#define R5XX_DATATYPE_RGB565 4
|
||||
#define R5XX_DATATYPE_RGB888 5
|
||||
#define R5XX_DATATYPE_ARGB8888 6
|
||||
#define R5XX_DATATYPE_RGB332 7
|
||||
#define R5XX_DATATYPE_Y8 8
|
||||
#define R5XX_DATATYPE_RGB8 9
|
||||
#define R5XX_DATATYPE_CI16 10
|
||||
#define R5XX_DATATYPE_VYUY_422 11
|
||||
#define R5XX_DATATYPE_YVYU_422 12
|
||||
#define R5XX_DATATYPE_AYUV_444 14
|
||||
#define R5XX_DATATYPE_ARGB4444 15
|
||||
|
||||
#define R5XX_RBBM_SOFT_RESET 0x00f0
|
||||
# define R5XX_SOFT_RESET_CP (1 << 0)
|
||||
# define R5XX_SOFT_RESET_HI (1 << 1)
|
||||
# define R5XX_SOFT_RESET_SE (1 << 2)
|
||||
# define R5XX_SOFT_RESET_RE (1 << 3)
|
||||
# define R5XX_SOFT_RESET_PP (1 << 4)
|
||||
# define R5XX_SOFT_RESET_E2 (1 << 5)
|
||||
# define R5XX_SOFT_RESET_RB (1 << 6)
|
||||
# define R5XX_SOFT_RESET_HDP (1 << 7)
|
||||
|
||||
#define R5XX_HOST_PATH_CNTL 0x0130
|
||||
# define R5XX_HDP_SOFT_RESET (1 << 26)
|
||||
# define R5XX_HDP_APER_CNTL (1 << 23)
|
||||
|
||||
#define R5XX_SURFACE_CNTL 0x0b00
|
||||
# define R5XX_SURF_TRANSLATION_DIS (1 << 8)
|
||||
# define R5XX_NONSURF_AP0_SWP_16BPP (1 << 20)
|
||||
# define R5XX_NONSURF_AP0_SWP_32BPP (1 << 21)
|
||||
# define R5XX_NONSURF_AP1_SWP_16BPP (1 << 22)
|
||||
# define R5XX_NONSURF_AP1_SWP_32BPP (1 << 23)
|
||||
|
||||
#define R5XX_SURFACE0_INFO 0x0b0c
|
||||
# define R5XX_SURF_TILE_COLOR_MACRO (0 << 16)
|
||||
# define R5XX_SURF_TILE_COLOR_BOTH (1 << 16)
|
||||
# define R5XX_SURF_TILE_DEPTH_32BPP (2 << 16)
|
||||
# define R5XX_SURF_TILE_DEPTH_16BPP (3 << 16)
|
||||
# define R5XX_SURF_AP0_SWP_16BPP (1 << 20)
|
||||
# define R5XX_SURF_AP0_SWP_32BPP (1 << 21)
|
||||
# define R5XX_SURF_AP1_SWP_16BPP (1 << 22)
|
||||
# define R5XX_SURF_AP1_SWP_32BPP (1 << 23)
|
||||
#define R5XX_SURFACE0_LOWER_BOUND 0x0b04
|
||||
#define R5XX_SURFACE0_UPPER_BOUND 0x0b08
|
||||
|
||||
#define R5XX_RBBM_STATUS 0x0e40
|
||||
# define R5XX_RBBM_FIFOCNT_MASK 0x007f
|
||||
# define R5XX_RBBM_ACTIVE (1 << 31)
|
||||
|
||||
#define R5XX_SRC_PITCH_OFFSET 0x1428
|
||||
#define R5XX_DST_PITCH_OFFSET 0x142c
|
||||
|
||||
#define R5XX_SRC_Y_X 0x1434
|
||||
#define R5XX_DST_Y_X 0x1438
|
||||
#define R5XX_DST_HEIGHT_WIDTH 0x143c
|
||||
|
||||
#define R5XX_DP_GUI_MASTER_CNTL 0x146c
|
||||
# define R5XX_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
|
||||
# define R5XX_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
|
||||
# define R5XX_GMC_SRC_CLIPPING (1 << 2)
|
||||
# define R5XX_GMC_DST_CLIPPING (1 << 3)
|
||||
# define R5XX_GMC_BRUSH_DATATYPE_MASK (0x0f << 4)
|
||||
# define R5XX_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4)
|
||||
# define R5XX_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4)
|
||||
# define R5XX_GMC_BRUSH_8x8_COLOR (10 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_COLOR (12 << 4)
|
||||
# define R5XX_GMC_BRUSH_SOLID_COLOR (13 << 4)
|
||||
# define R5XX_GMC_BRUSH_NONE (15 << 4)
|
||||
# define R5XX_GMC_DST_8BPP_CI (2 << 8)
|
||||
# define R5XX_GMC_DST_15BPP (3 << 8)
|
||||
# define R5XX_GMC_DST_16BPP (4 << 8)
|
||||
# define R5XX_GMC_DST_24BPP (5 << 8)
|
||||
# define R5XX_GMC_DST_32BPP (6 << 8)
|
||||
# define R5XX_GMC_DST_8BPP_RGB (7 << 8)
|
||||
# define R5XX_GMC_DST_Y8 (8 << 8)
|
||||
# define R5XX_GMC_DST_RGB8 (9 << 8)
|
||||
# define R5XX_GMC_DST_VYUY (11 << 8)
|
||||
# define R5XX_GMC_DST_YVYU (12 << 8)
|
||||
# define R5XX_GMC_DST_AYUV444 (14 << 8)
|
||||
# define R5XX_GMC_DST_ARGB4444 (15 << 8)
|
||||
# define R5XX_GMC_DST_DATATYPE_MASK (0x0f << 8)
|
||||
# define R5XX_GMC_DST_DATATYPE_SHIFT 8
|
||||
# define R5XX_GMC_SRC_DATATYPE_MASK (3 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_COLOR (3 << 12)
|
||||
# define R5XX_GMC_BYTE_PIX_ORDER (1 << 14)
|
||||
# define R5XX_GMC_BYTE_MSB_TO_LSB (0 << 14)
|
||||
# define R5XX_GMC_BYTE_LSB_TO_MSB (1 << 14)
|
||||
# define R5XX_GMC_CONVERSION_TEMP (1 << 15)
|
||||
# define R5XX_GMC_CONVERSION_TEMP_6500 (0 << 15)
|
||||
# define R5XX_GMC_CONVERSION_TEMP_9300 (1 << 15)
|
||||
# define R5XX_GMC_ROP3_MASK (0xff << 16)
|
||||
# define R5XX_DP_SRC_SOURCE_MASK (7 << 24)
|
||||
# define R5XX_DP_SRC_SOURCE_MEMORY (2 << 24)
|
||||
# define R5XX_DP_SRC_SOURCE_HOST_DATA (3 << 24)
|
||||
# define R5XX_GMC_3D_FCN_EN (1 << 27)
|
||||
# define R5XX_GMC_CLR_CMP_CNTL_DIS (1 << 28)
|
||||
# define R5XX_GMC_AUX_CLIP_DIS (1 << 29)
|
||||
# define R5XX_GMC_WR_MSK_DIS (1 << 30)
|
||||
# define R5XX_GMC_LD_BRUSH_Y_X (1 << 31)
|
||||
# define R5XX_ROP3_ZERO 0x00000000
|
||||
# define R5XX_ROP3_DSa 0x00880000
|
||||
# define R5XX_ROP3_SDna 0x00440000
|
||||
# define R5XX_ROP3_S 0x00cc0000
|
||||
# define R5XX_ROP3_DSna 0x00220000
|
||||
# define R5XX_ROP3_D 0x00aa0000
|
||||
# define R5XX_ROP3_DSx 0x00660000
|
||||
# define R5XX_ROP3_DSo 0x00ee0000
|
||||
# define R5XX_ROP3_DSon 0x00110000
|
||||
# define R5XX_ROP3_DSxn 0x00990000
|
||||
# define R5XX_ROP3_Dn 0x00550000
|
||||
# define R5XX_ROP3_SDno 0x00dd0000
|
||||
# define R5XX_ROP3_Sn 0x00330000
|
||||
# define R5XX_ROP3_DSno 0x00bb0000
|
||||
# define R5XX_ROP3_DSan 0x00770000
|
||||
# define R5XX_ROP3_ONE 0x00ff0000
|
||||
# define R5XX_ROP3_DPa 0x00a00000
|
||||
# define R5XX_ROP3_PDna 0x00500000
|
||||
# define R5XX_ROP3_P 0x00f00000
|
||||
# define R5XX_ROP3_DPna 0x000a0000
|
||||
# define R5XX_ROP3_D 0x00aa0000
|
||||
# define R5XX_ROP3_DPx 0x005a0000
|
||||
# define R5XX_ROP3_DPo 0x00fa0000
|
||||
# define R5XX_ROP3_DPon 0x00050000
|
||||
# define R5XX_ROP3_PDxn 0x00a50000
|
||||
# define R5XX_ROP3_PDno 0x00f50000
|
||||
# define R5XX_ROP3_Pn 0x000f0000
|
||||
# define R5XX_ROP3_DPno 0x00af0000
|
||||
# define R5XX_ROP3_DPan 0x005f0000
|
||||
|
||||
#define R5XX_BRUSH_Y_X 0x1474
|
||||
#define R5XX_DP_BRUSH_BKGD_CLR 0x1478
|
||||
#define R5XX_DP_BRUSH_FRGD_CLR 0x147c
|
||||
#define R5XX_BRUSH_DATA0 0x1480
|
||||
#define R5XX_BRUSH_DATA1 0x1484
|
||||
|
||||
#define R5XX_DST_WIDTH_HEIGHT 0x1598
|
||||
|
||||
#define R5XX_CLR_CMP_CNTL 0x15c0
|
||||
# define R5XX_SRC_CMP_EQ_COLOR (4 << 0)
|
||||
# define R5XX_SRC_CMP_NEQ_COLOR (5 << 0)
|
||||
# define R5XX_CLR_CMP_SRC_SOURCE (1 << 24)
|
||||
|
||||
#define R5XX_CLR_CMP_CLR_SRC 0x15c4
|
||||
|
||||
#define R5XX_CLR_CMP_MASK 0x15cc
|
||||
# define R5XX_CLR_CMP_MSK 0xffffffff
|
||||
|
||||
#define R5XX_DP_SRC_BKGD_CLR 0x15dc
|
||||
#define R5XX_DP_SRC_FRGD_CLR 0x15d8
|
||||
|
||||
#define R5XX_DST_LINE_START 0x1600
|
||||
#define R5XX_DST_LINE_END 0x1604
|
||||
#define R5XX_DST_LINE_PATCOUNT 0x1608
|
||||
# define R5XX_BRES_CNTL_SHIFT 8
|
||||
|
||||
#define R5XX_DP_CNTL 0x16c0
|
||||
# define R5XX_DST_X_LEFT_TO_RIGHT (1 << 0)
|
||||
# define R5XX_DST_Y_TOP_TO_BOTTOM (1 << 1)
|
||||
# define R5XX_DP_DST_TILE_LINEAR (0 << 3)
|
||||
# define R5XX_DP_DST_TILE_MACRO (1 << 3)
|
||||
# define R5XX_DP_DST_TILE_MICRO (2 << 3)
|
||||
# define R5XX_DP_DST_TILE_BOTH (3 << 3)
|
||||
|
||||
#define R5XX_DP_DATATYPE 0x16c4
|
||||
# define R5XX_HOST_BIG_ENDIAN_EN (1 << 29)
|
||||
|
||||
#define R5XX_DP_WRITE_MASK 0x16cc
|
||||
|
||||
#define R5XX_DEFAULT_SC_BOTTOM_RIGHT 0x16e8
|
||||
# define R5XX_DEFAULT_SC_RIGHT_MAX (0x1fff << 0)
|
||||
# define R5XX_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16)
|
||||
|
||||
#define R5XX_SC_TOP_LEFT 0x16ec
|
||||
#define R5XX_SC_BOTTOM_RIGHT 0x16f0
|
||||
# define R5XX_SC_SIGN_MASK_LO 0x8000
|
||||
# define R5XX_SC_SIGN_MASK_HI 0x80000000
|
||||
|
||||
#define R5XX_RBBM_GUICNTL 0x172c
|
||||
# define R5XX_HOST_DATA_SWAP_NONE (0 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_16BIT (1 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_32BIT (2 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_HDW (3 << 0)
|
||||
|
||||
#define R5XX_HOST_DATA0 0x17c0
|
||||
#define R5XX_HOST_DATA1 0x17c4
|
||||
#define R5XX_HOST_DATA2 0x17c8
|
||||
#define R5XX_HOST_DATA3 0x17cc
|
||||
#define R5XX_HOST_DATA4 0x17d0
|
||||
#define R5XX_HOST_DATA5 0x17d4
|
||||
#define R5XX_HOST_DATA6 0x17d8
|
||||
#define R5XX_HOST_DATA7 0x17dc
|
||||
#define R5XX_HOST_DATA_LAST 0x17e0
|
||||
|
||||
#define R5XX_RB3D_CNTL 0x1c3c
|
||||
# define R5XX_ALPHA_BLEND_ENABLE (1 << 0)
|
||||
# define R5XX_PLANE_MASK_ENABLE (1 << 1)
|
||||
# define R5XX_DITHER_ENABLE (1 << 2)
|
||||
# define R5XX_ROUND_ENABLE (1 << 3)
|
||||
# define R5XX_SCALE_DITHER_ENABLE (1 << 4)
|
||||
# define R5XX_DITHER_INIT (1 << 5)
|
||||
# define R5XX_ROP_ENABLE (1 << 6)
|
||||
# define R5XX_STENCIL_ENABLE (1 << 7)
|
||||
# define R5XX_Z_ENABLE (1 << 8)
|
||||
# define R5XX_DEPTH_XZ_OFFEST_ENABLE (1 << 9)
|
||||
# define R5XX_COLOR_FORMAT_ARGB1555 (3 << 10)
|
||||
# define R5XX_COLOR_FORMAT_RGB565 (4 << 10)
|
||||
# define R5XX_COLOR_FORMAT_ARGB8888 (6 << 10)
|
||||
# define R5XX_COLOR_FORMAT_RGB332 (7 << 10)
|
||||
# define R5XX_COLOR_FORMAT_Y8 (8 << 10)
|
||||
# define R5XX_COLOR_FORMAT_RGB8 (9 << 10)
|
||||
# define R5XX_COLOR_FORMAT_YUV422_VYUY (11 << 10)
|
||||
# define R5XX_COLOR_FORMAT_YUV422_YVYU (12 << 10)
|
||||
# define R5XX_COLOR_FORMAT_aYUV444 (14 << 10)
|
||||
# define R5XX_COLOR_FORMAT_ARGB4444 (15 << 10)
|
||||
# define R5XX_CLRCMP_FLIP_ENABLE (1 << 14)
|
||||
|
||||
#define R5XX_RB3D_DSTCACHE_CTLSTAT 0x325C
|
||||
# define R5XX_RB3D_DC_FLUSH (3 << 0)
|
||||
# define R5XX_RB3D_DC_FREE (3 << 2)
|
||||
# define R5XX_RB3D_DC_FLUSH_ALL 0xf
|
||||
# define R5XX_RB3D_DC_BUSY (1 << 31)
|
||||
|
||||
#define R5XX_RB3D_DSTCACHE_MODE 0x3258
|
||||
# define R5XX_RB3D_DC_CACHE_ENABLE (0)
|
||||
# define R5XX_RB3D_DC_2D_CACHE_DISABLE (1)
|
||||
# define R5XX_RB3D_DC_3D_CACHE_DISABLE (2)
|
||||
# define R5XX_RB3D_DC_CACHE_DISABLE (3)
|
||||
# define R5XX_RB3D_DC_2D_CACHE_LINESIZE_128 (1 << 2)
|
||||
# define R5XX_RB3D_DC_3D_CACHE_LINESIZE_128 (2 << 2)
|
||||
# define R5XX_RB3D_DC_2D_CACHE_AUTOFLUSH (1 << 8)
|
||||
# define R5XX_RB3D_DC_3D_CACHE_AUTOFLUSH (2 << 8)
|
||||
# define R200_RB3D_DC_2D_CACHE_AUTOFREE (1 << 10)
|
||||
# define R200_RB3D_DC_3D_CACHE_AUTOFREE (2 << 10)
|
||||
# define R5XX_RB3D_DC_FORCE_RMW (1 << 16)
|
||||
# define R5XX_RB3D_DC_DISABLE_RI_FILL (1 << 24)
|
||||
# define R5XX_RB3D_DC_DISABLE_RI_READ (1 << 25)
|
||||
|
||||
#endif /* _R5XX_2DREGS_H */
|
||||
273
drivers/video/ati2d/r5xx_regs.h
Normal file
273
drivers/video/ati2d/r5xx_regs.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 on 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 (including the
|
||||
* next paragraph) 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
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
||||
* THEIR SUPPLIERS 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.
|
||||
*/
|
||||
/* WARNING: the above is not a standard MIT license. */
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@xfree86.org>
|
||||
* Rickard E. Faith <faith@valinux.com>
|
||||
* Alan Hourihane <alanh@fairlite.demon.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef _R5XX_2DREGS_H
|
||||
# define _R5XX_2DREGS_H
|
||||
|
||||
#define R5XX_DATATYPE_VQ 0
|
||||
#define R5XX_DATATYPE_CI4 1
|
||||
#define R5XX_DATATYPE_CI8 2
|
||||
#define R5XX_DATATYPE_ARGB1555 3
|
||||
#define R5XX_DATATYPE_RGB565 4
|
||||
#define R5XX_DATATYPE_RGB888 5
|
||||
#define R5XX_DATATYPE_ARGB8888 6
|
||||
#define R5XX_DATATYPE_RGB332 7
|
||||
#define R5XX_DATATYPE_Y8 8
|
||||
#define R5XX_DATATYPE_RGB8 9
|
||||
#define R5XX_DATATYPE_CI16 10
|
||||
#define R5XX_DATATYPE_VYUY_422 11
|
||||
#define R5XX_DATATYPE_YVYU_422 12
|
||||
#define R5XX_DATATYPE_AYUV_444 14
|
||||
#define R5XX_DATATYPE_ARGB4444 15
|
||||
|
||||
#define R5XX_RBBM_SOFT_RESET 0x00f0
|
||||
# define R5XX_SOFT_RESET_CP (1 << 0)
|
||||
# define R5XX_SOFT_RESET_HI (1 << 1)
|
||||
# define R5XX_SOFT_RESET_SE (1 << 2)
|
||||
# define R5XX_SOFT_RESET_RE (1 << 3)
|
||||
# define R5XX_SOFT_RESET_PP (1 << 4)
|
||||
# define R5XX_SOFT_RESET_E2 (1 << 5)
|
||||
# define R5XX_SOFT_RESET_RB (1 << 6)
|
||||
# define R5XX_SOFT_RESET_HDP (1 << 7)
|
||||
|
||||
#define R5XX_HOST_PATH_CNTL 0x0130
|
||||
# define R5XX_HDP_SOFT_RESET (1 << 26)
|
||||
# define R5XX_HDP_APER_CNTL (1 << 23)
|
||||
|
||||
#define R5XX_SURFACE_CNTL 0x0b00
|
||||
# define R5XX_SURF_TRANSLATION_DIS (1 << 8)
|
||||
# define R5XX_NONSURF_AP0_SWP_16BPP (1 << 20)
|
||||
# define R5XX_NONSURF_AP0_SWP_32BPP (1 << 21)
|
||||
# define R5XX_NONSURF_AP1_SWP_16BPP (1 << 22)
|
||||
# define R5XX_NONSURF_AP1_SWP_32BPP (1 << 23)
|
||||
|
||||
#define R5XX_SURFACE0_INFO 0x0b0c
|
||||
# define R5XX_SURF_TILE_COLOR_MACRO (0 << 16)
|
||||
# define R5XX_SURF_TILE_COLOR_BOTH (1 << 16)
|
||||
# define R5XX_SURF_TILE_DEPTH_32BPP (2 << 16)
|
||||
# define R5XX_SURF_TILE_DEPTH_16BPP (3 << 16)
|
||||
# define R5XX_SURF_AP0_SWP_16BPP (1 << 20)
|
||||
# define R5XX_SURF_AP0_SWP_32BPP (1 << 21)
|
||||
# define R5XX_SURF_AP1_SWP_16BPP (1 << 22)
|
||||
# define R5XX_SURF_AP1_SWP_32BPP (1 << 23)
|
||||
#define R5XX_SURFACE0_LOWER_BOUND 0x0b04
|
||||
#define R5XX_SURFACE0_UPPER_BOUND 0x0b08
|
||||
|
||||
#define R5XX_RBBM_STATUS 0x0e40
|
||||
# define R5XX_RBBM_FIFOCNT_MASK 0x007f
|
||||
# define R5XX_RBBM_ACTIVE (1 << 31)
|
||||
|
||||
#define R5XX_SRC_PITCH_OFFSET 0x1428
|
||||
#define R5XX_DST_PITCH_OFFSET 0x142c
|
||||
|
||||
#define R5XX_SRC_Y_X 0x1434
|
||||
#define R5XX_DST_Y_X 0x1438
|
||||
#define R5XX_DST_HEIGHT_WIDTH 0x143c
|
||||
|
||||
#define R5XX_DP_GUI_MASTER_CNTL 0x146c
|
||||
# define R5XX_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
|
||||
# define R5XX_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
|
||||
# define R5XX_GMC_SRC_CLIPPING (1 << 2)
|
||||
# define R5XX_GMC_DST_CLIPPING (1 << 3)
|
||||
# define R5XX_GMC_BRUSH_DATATYPE_MASK (0x0f << 4)
|
||||
# define R5XX_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4)
|
||||
# define R5XX_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4)
|
||||
# define R5XX_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4)
|
||||
# define R5XX_GMC_BRUSH_8x8_COLOR (10 << 4)
|
||||
# define R5XX_GMC_BRUSH_1X8_COLOR (12 << 4)
|
||||
# define R5XX_GMC_BRUSH_SOLID_COLOR (13 << 4)
|
||||
# define R5XX_GMC_BRUSH_NONE (15 << 4)
|
||||
# define R5XX_GMC_DST_8BPP_CI (2 << 8)
|
||||
# define R5XX_GMC_DST_15BPP (3 << 8)
|
||||
# define R5XX_GMC_DST_16BPP (4 << 8)
|
||||
# define R5XX_GMC_DST_24BPP (5 << 8)
|
||||
# define R5XX_GMC_DST_32BPP (6 << 8)
|
||||
# define R5XX_GMC_DST_8BPP_RGB (7 << 8)
|
||||
# define R5XX_GMC_DST_Y8 (8 << 8)
|
||||
# define R5XX_GMC_DST_RGB8 (9 << 8)
|
||||
# define R5XX_GMC_DST_VYUY (11 << 8)
|
||||
# define R5XX_GMC_DST_YVYU (12 << 8)
|
||||
# define R5XX_GMC_DST_AYUV444 (14 << 8)
|
||||
# define R5XX_GMC_DST_ARGB4444 (15 << 8)
|
||||
# define R5XX_GMC_DST_DATATYPE_MASK (0x0f << 8)
|
||||
# define R5XX_GMC_DST_DATATYPE_SHIFT 8
|
||||
# define R5XX_GMC_SRC_DATATYPE_MASK (3 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12)
|
||||
# define R5XX_GMC_SRC_DATATYPE_COLOR (3 << 12)
|
||||
# define R5XX_GMC_BYTE_PIX_ORDER (1 << 14)
|
||||
# define R5XX_GMC_BYTE_MSB_TO_LSB (0 << 14)
|
||||
# define R5XX_GMC_BYTE_LSB_TO_MSB (1 << 14)
|
||||
# define R5XX_GMC_CONVERSION_TEMP (1 << 15)
|
||||
# define R5XX_GMC_CONVERSION_TEMP_6500 (0 << 15)
|
||||
# define R5XX_GMC_CONVERSION_TEMP_9300 (1 << 15)
|
||||
# define R5XX_GMC_ROP3_MASK (0xff << 16)
|
||||
# define R5XX_DP_SRC_SOURCE_MASK (7 << 24)
|
||||
# define R5XX_DP_SRC_SOURCE_MEMORY (2 << 24)
|
||||
# define R5XX_DP_SRC_SOURCE_HOST_DATA (3 << 24)
|
||||
# define R5XX_GMC_3D_FCN_EN (1 << 27)
|
||||
# define R5XX_GMC_CLR_CMP_CNTL_DIS (1 << 28)
|
||||
# define R5XX_GMC_AUX_CLIP_DIS (1 << 29)
|
||||
# define R5XX_GMC_WR_MSK_DIS (1 << 30)
|
||||
# define R5XX_GMC_LD_BRUSH_Y_X (1 << 31)
|
||||
# define R5XX_ROP3_ZERO 0x00000000
|
||||
# define R5XX_ROP3_DSa 0x00880000
|
||||
# define R5XX_ROP3_SDna 0x00440000
|
||||
# define R5XX_ROP3_S 0x00cc0000
|
||||
# define R5XX_ROP3_DSna 0x00220000
|
||||
# define R5XX_ROP3_D 0x00aa0000
|
||||
# define R5XX_ROP3_DSx 0x00660000
|
||||
# define R5XX_ROP3_DSo 0x00ee0000
|
||||
# define R5XX_ROP3_DSon 0x00110000
|
||||
# define R5XX_ROP3_DSxn 0x00990000
|
||||
# define R5XX_ROP3_Dn 0x00550000
|
||||
# define R5XX_ROP3_SDno 0x00dd0000
|
||||
# define R5XX_ROP3_Sn 0x00330000
|
||||
# define R5XX_ROP3_DSno 0x00bb0000
|
||||
# define R5XX_ROP3_DSan 0x00770000
|
||||
# define R5XX_ROP3_ONE 0x00ff0000
|
||||
# define R5XX_ROP3_DPa 0x00a00000
|
||||
# define R5XX_ROP3_PDna 0x00500000
|
||||
# define R5XX_ROP3_P 0x00f00000
|
||||
# define R5XX_ROP3_DPna 0x000a0000
|
||||
# define R5XX_ROP3_D 0x00aa0000
|
||||
# define R5XX_ROP3_DPx 0x005a0000
|
||||
# define R5XX_ROP3_DPo 0x00fa0000
|
||||
# define R5XX_ROP3_DPon 0x00050000
|
||||
# define R5XX_ROP3_PDxn 0x00a50000
|
||||
# define R5XX_ROP3_PDno 0x00f50000
|
||||
# define R5XX_ROP3_Pn 0x000f0000
|
||||
# define R5XX_ROP3_DPno 0x00af0000
|
||||
# define R5XX_ROP3_DPan 0x005f0000
|
||||
|
||||
#define R5XX_BRUSH_Y_X 0x1474
|
||||
#define R5XX_DP_BRUSH_BKGD_CLR 0x1478
|
||||
#define R5XX_DP_BRUSH_FRGD_CLR 0x147c
|
||||
#define R5XX_BRUSH_DATA0 0x1480
|
||||
#define R5XX_BRUSH_DATA1 0x1484
|
||||
|
||||
#define R5XX_DST_WIDTH_HEIGHT 0x1598
|
||||
|
||||
#define R5XX_CLR_CMP_CNTL 0x15c0
|
||||
# define R5XX_SRC_CMP_EQ_COLOR (4 << 0)
|
||||
# define R5XX_SRC_CMP_NEQ_COLOR (5 << 0)
|
||||
# define R5XX_CLR_CMP_SRC_SOURCE (1 << 24)
|
||||
|
||||
#define R5XX_CLR_CMP_CLR_SRC 0x15c4
|
||||
|
||||
#define R5XX_CLR_CMP_MASK 0x15cc
|
||||
# define R5XX_CLR_CMP_MSK 0xffffffff
|
||||
|
||||
#define R5XX_DP_SRC_BKGD_CLR 0x15dc
|
||||
#define R5XX_DP_SRC_FRGD_CLR 0x15d8
|
||||
|
||||
#define R5XX_DST_LINE_START 0x1600
|
||||
#define R5XX_DST_LINE_END 0x1604
|
||||
#define R5XX_DST_LINE_PATCOUNT 0x1608
|
||||
# define R5XX_BRES_CNTL_SHIFT 8
|
||||
|
||||
#define R5XX_DP_CNTL 0x16c0
|
||||
# define R5XX_DST_X_LEFT_TO_RIGHT (1 << 0)
|
||||
# define R5XX_DST_Y_TOP_TO_BOTTOM (1 << 1)
|
||||
# define R5XX_DP_DST_TILE_LINEAR (0 << 3)
|
||||
# define R5XX_DP_DST_TILE_MACRO (1 << 3)
|
||||
# define R5XX_DP_DST_TILE_MICRO (2 << 3)
|
||||
# define R5XX_DP_DST_TILE_BOTH (3 << 3)
|
||||
|
||||
#define R5XX_DP_DATATYPE 0x16c4
|
||||
# define R5XX_HOST_BIG_ENDIAN_EN (1 << 29)
|
||||
|
||||
#define R5XX_DP_WRITE_MASK 0x16cc
|
||||
|
||||
#define R5XX_DEFAULT_SC_BOTTOM_RIGHT 0x16e8
|
||||
# define R5XX_DEFAULT_SC_RIGHT_MAX (0x1fff << 0)
|
||||
# define R5XX_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16)
|
||||
|
||||
#define R5XX_SC_TOP_LEFT 0x16ec
|
||||
#define R5XX_SC_BOTTOM_RIGHT 0x16f0
|
||||
# define R5XX_SC_SIGN_MASK_LO 0x8000
|
||||
# define R5XX_SC_SIGN_MASK_HI 0x80000000
|
||||
|
||||
#define R5XX_DST_PIPE_CONFIG 0x170c
|
||||
# define R5XX_PIPE_AUTO_CONFIG (1 << 31)
|
||||
|
||||
#define R5XX_DSTCACHE_CTLSTAT 0x1714
|
||||
# define R5XX_DSTCACHE_FLUSH_2D (1 << 0)
|
||||
# define R5XX_DSTCACHE_FREE_2D (1 << 2)
|
||||
# define R5XX_DSTCACHE_FLUSH_ALL (R5XX_DSTCACHE_FLUSH_2D | R5XX_DSTCACHE_FREE_2D)
|
||||
# define R5XX_DSTCACHE_BUSY (1 << 31)
|
||||
|
||||
#define R5XX_WAIT_UNTIL 0x1720
|
||||
# define R5XX_WAIT_2D_IDLECLEAN (1 << 16)
|
||||
# define R5XX_WAIT_3D_IDLECLEAN (1 << 17)
|
||||
|
||||
#define R5XX_RBBM_GUICNTL 0x172c
|
||||
# define R5XX_HOST_DATA_SWAP_NONE (0 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_16BIT (1 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_32BIT (2 << 0)
|
||||
# define R5XX_HOST_DATA_SWAP_HDW (3 << 0)
|
||||
|
||||
#define R5XX_HOST_DATA0 0x17c0
|
||||
#define R5XX_HOST_DATA1 0x17c4
|
||||
#define R5XX_HOST_DATA2 0x17c8
|
||||
#define R5XX_HOST_DATA3 0x17cc
|
||||
#define R5XX_HOST_DATA4 0x17d0
|
||||
#define R5XX_HOST_DATA5 0x17d4
|
||||
#define R5XX_HOST_DATA6 0x17d8
|
||||
#define R5XX_HOST_DATA7 0x17dc
|
||||
#define R5XX_HOST_DATA_LAST 0x17e0
|
||||
|
||||
#define R5XX_RB2D_DSTCACHE_MODE 0x3428
|
||||
# define R5XX_RB2D_DC_AUTOFLUSH_ENABLE (1 << 8)
|
||||
# define R5XX_RB2D_DC_DISABLE_IGNORE_PE (1 << 17)
|
||||
|
||||
#define R5XX_GB_TILE_CONFIG 0x4018
|
||||
# define R5XX_ENABLE_TILING (1 << 0)
|
||||
# define R5XX_PIPE_COUNT_RV350 (0 << 1)
|
||||
# define R5XX_PIPE_COUNT_R300 (3 << 1)
|
||||
# define R5XX_PIPE_COUNT_R420_3P (6 << 1)
|
||||
# define R5XX_PIPE_COUNT_R420 (7 << 1)
|
||||
# define R5XX_TILE_SIZE_8 (0 << 4)
|
||||
# define R5XX_TILE_SIZE_16 (1 << 4)
|
||||
# define R5XX_TILE_SIZE_32 (2 << 4)
|
||||
# define R5XX_SUBPIXEL_1_12 (0 << 16)
|
||||
# define R5XX_SUBPIXEL_1_16 (1 << 16)
|
||||
|
||||
#endif /* _R5XX_2DREGS_H */
|
||||
306
drivers/video/ati2d/radeon_chipinfo_gen.h
Normal file
306
drivers/video/ati2d/radeon_chipinfo_gen.h
Normal file
@@ -0,0 +1,306 @@
|
||||
/* This file is autogenerated please do not edit */
|
||||
RADEONCardInfo RADEONCards[] = {
|
||||
{ 0x3150, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x3151, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x3152, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x3154, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x3E50, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x3E54, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x4136, CHIP_FAMILY_RS100, 0, 1, 0, 0, 1 },
|
||||
{ 0x4137, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 },
|
||||
{ 0x4144, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4145, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4146, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4147, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4148, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4149, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x414A, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x414B, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4150, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4151, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4152, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4153, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4154, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4155, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4156, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4237, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 },
|
||||
{ 0x4242, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
|
||||
{ 0x4243, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
|
||||
{ 0x4336, CHIP_FAMILY_RS100, 1, 1, 0, 0, 1 },
|
||||
{ 0x4337, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 },
|
||||
{ 0x4437, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 },
|
||||
{ 0x4966, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 },
|
||||
{ 0x4967, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A48, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A49, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A4A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A4B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A4D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A4E, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 },
|
||||
{ 0x4A4F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4A50, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4B49, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4B4A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4B4B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4B4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x4C57, CHIP_FAMILY_RV200, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C58, CHIP_FAMILY_RV200, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C59, CHIP_FAMILY_RV100, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C5A, CHIP_FAMILY_RV100, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C64, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C66, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 },
|
||||
{ 0x4C67, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E44, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E45, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E46, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E47, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E48, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E49, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E4A, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E4B, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 },
|
||||
{ 0x4E50, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E51, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E52, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E53, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E54, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x4E56, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 },
|
||||
{ 0x5144, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 },
|
||||
{ 0x5145, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 },
|
||||
{ 0x5146, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 },
|
||||
{ 0x5147, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 },
|
||||
{ 0x5148, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
|
||||
{ 0x514C, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
|
||||
{ 0x514D, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
|
||||
{ 0x5157, CHIP_FAMILY_RV200, 0, 0, 0, 0, 0 },
|
||||
{ 0x5158, CHIP_FAMILY_RV200, 0, 0, 0, 0, 0 },
|
||||
{ 0x5159, CHIP_FAMILY_RV100, 0, 0, 0, 0, 0 },
|
||||
{ 0x515A, CHIP_FAMILY_RV100, 0, 0, 0, 0, 0 },
|
||||
{ 0x515E, CHIP_FAMILY_RV100, 0, 0, 1, 0, 0 },
|
||||
{ 0x5460, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x5462, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x5464, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
|
||||
{ 0x5548, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5549, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554E, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x554F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5550, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5551, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5552, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5554, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x564A, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 },
|
||||
{ 0x564B, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 },
|
||||
{ 0x564F, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 },
|
||||
{ 0x5652, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 },
|
||||
{ 0x5653, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 },
|
||||
{ 0x5657, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 1 },
|
||||
{ 0x5835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 1 },
|
||||
{ 0x5954, CHIP_FAMILY_RS480, 0, 1, 0, 0, 1 },
|
||||
{ 0x5955, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 },
|
||||
{ 0x5960, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
|
||||
{ 0x5961, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
|
||||
{ 0x5962, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
|
||||
{ 0x5964, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
|
||||
{ 0x5965, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
|
||||
{ 0x5969, CHIP_FAMILY_RV100, 0, 0, 1, 0, 0 },
|
||||
{ 0x5974, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 },
|
||||
{ 0x5975, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 },
|
||||
{ 0x5A41, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 },
|
||||
{ 0x5A42, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 },
|
||||
{ 0x5A61, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 },
|
||||
{ 0x5A62, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 },
|
||||
{ 0x5B60, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x5B62, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x5B63, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x5B64, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x5B65, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
|
||||
{ 0x5C61, CHIP_FAMILY_RV280, 1, 0, 0, 0, 0 },
|
||||
{ 0x5C63, CHIP_FAMILY_RV280, 1, 0, 0, 0, 0 },
|
||||
{ 0x5D48, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 },
|
||||
{ 0x5D49, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 },
|
||||
{ 0x5D4A, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 },
|
||||
{ 0x5D4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D4D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D4E, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D4F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D50, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D52, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5D57, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E48, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E4A, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E4B, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E4C, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E4D, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x5E4F, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
|
||||
{ 0x7100, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x7101, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
|
||||
{ 0x7102, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
|
||||
{ 0x7103, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
|
||||
{ 0x7104, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x7105, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x7106, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
|
||||
{ 0x7108, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x7109, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x710A, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x710B, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x710C, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x710E, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x710F, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
|
||||
{ 0x7140, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7141, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7142, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7143, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7144, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x7145, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x7146, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7147, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7149, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x714A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x714B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x714C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x714D, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x714E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x714F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7151, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7152, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7153, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x715E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x715F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7180, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7181, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7183, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7186, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x7187, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7188, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x718A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x718B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x718C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x718D, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x718F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7193, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7196, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x719B, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x719F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C0, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C1, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C3, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x71C5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x71C6, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71C7, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71CD, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71CE, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71D2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71D4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x71D5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x71D6, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x71DA, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
|
||||
{ 0x71DE, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
|
||||
{ 0x7200, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
|
||||
{ 0x7210, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x7211, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
|
||||
{ 0x7240, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7243, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7244, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7245, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7246, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7247, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7248, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7249, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724A, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724B, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724C, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724D, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724E, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x724F, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
|
||||
{ 0x7280, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
|
||||
{ 0x7281, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7283, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7284, CHIP_FAMILY_R580, 1, 0, 0, 0, 0 },
|
||||
{ 0x7287, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7288, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
|
||||
{ 0x7289, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
|
||||
{ 0x728B, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
|
||||
{ 0x728C, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
|
||||
{ 0x7290, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7291, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7293, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7297, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
|
||||
{ 0x7834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 1 },
|
||||
{ 0x7835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 1 },
|
||||
{ 0x791E, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 },
|
||||
{ 0x791F, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 },
|
||||
{ 0x793F, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 },
|
||||
{ 0x7941, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 },
|
||||
{ 0x7942, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 },
|
||||
{ 0x796C, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
|
||||
{ 0x796D, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
|
||||
{ 0x796E, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
|
||||
{ 0x796F, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
|
||||
{ 0x9400, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x9401, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x9402, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x9403, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x9405, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x940A, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x940B, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x940F, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
|
||||
{ 0x9440, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 },
|
||||
{ 0x9441, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 },
|
||||
{ 0x9442, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C0, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C1, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C3, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C4, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C5, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C6, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C7, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x94C8, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
|
||||
{ 0x94C9, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
|
||||
{ 0x94CB, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
|
||||
{ 0x94CC, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
|
||||
{ 0x9500, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9501, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9505, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9507, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x950F, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9511, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9515, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 },
|
||||
{ 0x9580, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x9581, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
|
||||
{ 0x9583, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
|
||||
{ 0x9586, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x9587, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x9588, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x9589, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x958A, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x958B, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
|
||||
{ 0x958C, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x958D, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x958E, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
|
||||
{ 0x95C0, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x95C5, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x95C7, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x95C2, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
|
||||
{ 0x95C4, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
|
||||
{ 0x95CD, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x95CE, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x95CF, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
|
||||
{ 0x9590, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
|
||||
{ 0x9596, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
|
||||
{ 0x9597, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
|
||||
{ 0x9598, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
|
||||
{ 0x9599, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
|
||||
{ 0x9591, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
|
||||
{ 0x9593, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
|
||||
{ 0x9610, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
|
||||
{ 0x9611, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
|
||||
{ 0x9612, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
|
||||
{ 0x9613, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
|
||||
};
|
||||
307
drivers/video/ati2d/radeon_chipset_gen.h
Normal file
307
drivers/video/ati2d/radeon_chipset_gen.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/* This file is autogenerated please do not edit */
|
||||
static SymTabRec RADEONChipsets[] = {
|
||||
{ PCI_CHIP_RV380_3150, "ATI Radeon Mobility X600 (M24) 3150 (PCIE)" },
|
||||
{ PCI_CHIP_RV380_3151, "ATI FireMV 2400 (PCI)" },
|
||||
{ PCI_CHIP_RV380_3152, "ATI Radeon Mobility X300 (M24) 3152 (PCIE)" },
|
||||
{ PCI_CHIP_RV380_3154, "ATI FireGL M24 GL 3154 (PCIE)" },
|
||||
{ PCI_CHIP_RV380_3E50, "ATI Radeon X600 (RV380) 3E50 (PCIE)" },
|
||||
{ PCI_CHIP_RV380_3E54, "ATI FireGL V3200 (RV380) 3E54 (PCIE)" },
|
||||
{ PCI_CHIP_RS100_4136, "ATI Radeon IGP320 (A3) 4136" },
|
||||
{ PCI_CHIP_RS200_4137, "ATI Radeon IGP330/340/350 (A4) 4137" },
|
||||
{ PCI_CHIP_R300_AD, "ATI Radeon 9500 AD (AGP)" },
|
||||
{ PCI_CHIP_R300_AE, "ATI Radeon 9500 AE (AGP)" },
|
||||
{ PCI_CHIP_R300_AF, "ATI Radeon 9600TX AF (AGP)" },
|
||||
{ PCI_CHIP_R300_AG, "ATI FireGL Z1 AG (AGP)" },
|
||||
{ PCI_CHIP_R350_AH, "ATI Radeon 9800SE AH (AGP)" },
|
||||
{ PCI_CHIP_R350_AI, "ATI Radeon 9800 AI (AGP)" },
|
||||
{ PCI_CHIP_R350_AJ, "ATI Radeon 9800 AJ (AGP)" },
|
||||
{ PCI_CHIP_R350_AK, "ATI FireGL X2 AK (AGP)" },
|
||||
{ PCI_CHIP_RV350_AP, "ATI Radeon 9600 AP (AGP)" },
|
||||
{ PCI_CHIP_RV350_AQ, "ATI Radeon 9600SE AQ (AGP)" },
|
||||
{ PCI_CHIP_RV360_AR, "ATI Radeon 9600XT AR (AGP)" },
|
||||
{ PCI_CHIP_RV350_AS, "ATI Radeon 9600 AS (AGP)" },
|
||||
{ PCI_CHIP_RV350_AT, "ATI FireGL T2 AT (AGP)" },
|
||||
{ PCI_CHIP_RV350_4155, "ATI Radeon 9650" },
|
||||
{ PCI_CHIP_RV350_AV, "ATI FireGL RV360 AV (AGP)" },
|
||||
{ PCI_CHIP_RS250_4237, "ATI Radeon 7000 IGP (A4+) 4237" },
|
||||
{ PCI_CHIP_R200_BB, "ATI Radeon 8500 AIW BB (AGP)" },
|
||||
{ PCI_CHIP_R200_BC, "ATI Radeon 8500 AIW BC (AGP)" },
|
||||
{ PCI_CHIP_RS100_4336, "ATI Radeon IGP320M (U1) 4336" },
|
||||
{ PCI_CHIP_RS200_4337, "ATI Radeon IGP330M/340M/350M (U2) 4337" },
|
||||
{ PCI_CHIP_RS250_4437, "ATI Radeon Mobility 7000 IGP 4437" },
|
||||
{ PCI_CHIP_RV250_If, "ATI Radeon 9000/PRO If (AGP/PCI)" },
|
||||
{ PCI_CHIP_RV250_Ig, "ATI Radeon 9000 Ig (AGP/PCI)" },
|
||||
{ PCI_CHIP_R420_JH, "ATI Radeon X800 (R420) JH (AGP)" },
|
||||
{ PCI_CHIP_R420_JI, "ATI Radeon X800PRO (R420) JI (AGP)" },
|
||||
{ PCI_CHIP_R420_JJ, "ATI Radeon X800SE (R420) JJ (AGP)" },
|
||||
{ PCI_CHIP_R420_JK, "ATI Radeon X800 (R420) JK (AGP)" },
|
||||
{ PCI_CHIP_R420_JL, "ATI Radeon X800 (R420) JL (AGP)" },
|
||||
{ PCI_CHIP_R420_JM, "ATI FireGL X3 (R420) JM (AGP)" },
|
||||
{ PCI_CHIP_R420_JN, "ATI Radeon Mobility 9800 (M18) JN (AGP)" },
|
||||
{ PCI_CHIP_R420_4A4F, "ATI Radeon X800 SE (R420) (AGP)" },
|
||||
{ PCI_CHIP_R420_JP, "ATI Radeon X800XT (R420) JP (AGP)" },
|
||||
{ PCI_CHIP_R481_4B49, "ATI Radeon X850 XT (R480) (AGP)" },
|
||||
{ PCI_CHIP_R481_4B4A, "ATI Radeon X850 SE (R480) (AGP)" },
|
||||
{ PCI_CHIP_R481_4B4B, "ATI Radeon X850 PRO (R480) (AGP)" },
|
||||
{ PCI_CHIP_R481_4B4C, "ATI Radeon X850 XT PE (R480) (AGP)" },
|
||||
{ PCI_CHIP_RADEON_LW, "ATI Radeon Mobility M7 LW (AGP)" },
|
||||
{ PCI_CHIP_RADEON_LX, "ATI Mobility FireGL 7800 M7 LX (AGP)" },
|
||||
{ PCI_CHIP_RADEON_LY, "ATI Radeon Mobility M6 LY (AGP)" },
|
||||
{ PCI_CHIP_RADEON_LZ, "ATI Radeon Mobility M6 LZ (AGP)" },
|
||||
{ PCI_CHIP_RV250_Ld, "ATI FireGL Mobility 9000 (M9) Ld (AGP)" },
|
||||
{ PCI_CHIP_RV250_Lf, "ATI Radeon Mobility 9000 (M9) Lf (AGP)" },
|
||||
{ PCI_CHIP_RV250_Lg, "ATI Radeon Mobility 9000 (M9) Lg (AGP)" },
|
||||
{ PCI_CHIP_R300_ND, "ATI Radeon 9700 Pro ND (AGP)" },
|
||||
{ PCI_CHIP_R300_NE, "ATI Radeon 9700/9500Pro NE (AGP)" },
|
||||
{ PCI_CHIP_R300_NF, "ATI Radeon 9600TX NF (AGP)" },
|
||||
{ PCI_CHIP_R300_NG, "ATI FireGL X1 NG (AGP)" },
|
||||
{ PCI_CHIP_R350_NH, "ATI Radeon 9800PRO NH (AGP)" },
|
||||
{ PCI_CHIP_R350_NI, "ATI Radeon 9800 NI (AGP)" },
|
||||
{ PCI_CHIP_R360_NJ, "ATI FireGL X2 NK (AGP)" },
|
||||
{ PCI_CHIP_R350_NK, "ATI Radeon 9800XT NJ (AGP)" },
|
||||
{ PCI_CHIP_RV350_NP, "ATI Radeon Mobility 9600/9700 (M10/M11) NP (AGP)" },
|
||||
{ PCI_CHIP_RV350_NQ, "ATI Radeon Mobility 9600 (M10) NQ (AGP)" },
|
||||
{ PCI_CHIP_RV350_NR, "ATI Radeon Mobility 9600 (M11) NR (AGP)" },
|
||||
{ PCI_CHIP_RV350_NS, "ATI Radeon Mobility 9600 (M10) NS (AGP)" },
|
||||
{ PCI_CHIP_RV350_NT, "ATI FireGL Mobility T2 (M10) NT (AGP)" },
|
||||
{ PCI_CHIP_RV350_NV, "ATI FireGL Mobility T2e (M11) NV (AGP)" },
|
||||
{ PCI_CHIP_RADEON_QD, "ATI Radeon QD (AGP)" },
|
||||
{ PCI_CHIP_RADEON_QE, "ATI Radeon QE (AGP)" },
|
||||
{ PCI_CHIP_RADEON_QF, "ATI Radeon QF (AGP)" },
|
||||
{ PCI_CHIP_RADEON_QG, "ATI Radeon QG (AGP)" },
|
||||
{ PCI_CHIP_R200_QH, "ATI FireGL 8700/8800 QH (AGP)" },
|
||||
{ PCI_CHIP_R200_QL, "ATI Radeon 8500 QL (AGP)" },
|
||||
{ PCI_CHIP_R200_QM, "ATI Radeon 9100 QM (AGP)" },
|
||||
{ PCI_CHIP_RV200_QW, "ATI Radeon 7500 QW (AGP/PCI)" },
|
||||
{ PCI_CHIP_RV200_QX, "ATI Radeon 7500 QX (AGP/PCI)" },
|
||||
{ PCI_CHIP_RV100_QY, "ATI Radeon VE/7000 QY (AGP/PCI)" },
|
||||
{ PCI_CHIP_RV100_QZ, "ATI Radeon VE/7000 QZ (AGP/PCI)" },
|
||||
{ PCI_CHIP_RN50_515E, "ATI ES1000 515E (PCI)" },
|
||||
{ PCI_CHIP_RV370_5460, "ATI Radeon Mobility X300 (M22) 5460 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5462, "ATI Radeon Mobility X600 SE (M24C) 5462 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5464, "ATI FireGL M22 GL 5464 (PCIE)" },
|
||||
{ PCI_CHIP_R423_UH, "ATI Radeon X800 (R423) UH (PCIE)" },
|
||||
{ PCI_CHIP_R423_UI, "ATI Radeon X800PRO (R423) UI (PCIE)" },
|
||||
{ PCI_CHIP_R423_UJ, "ATI Radeon X800LE (R423) UJ (PCIE)" },
|
||||
{ PCI_CHIP_R423_UK, "ATI Radeon X800SE (R423) UK (PCIE)" },
|
||||
{ PCI_CHIP_R430_554C, "ATI Radeon X800 XTP (R430) (PCIE)" },
|
||||
{ PCI_CHIP_R430_554D, "ATI Radeon X800 XL (R430) (PCIE)" },
|
||||
{ PCI_CHIP_R430_554E, "ATI Radeon X800 SE (R430) (PCIE)" },
|
||||
{ PCI_CHIP_R430_554F, "ATI Radeon X800 (R430) (PCIE)" },
|
||||
{ PCI_CHIP_R423_5550, "ATI FireGL V7100 (R423) (PCIE)" },
|
||||
{ PCI_CHIP_R423_UQ, "ATI FireGL V5100 (R423) UQ (PCIE)" },
|
||||
{ PCI_CHIP_R423_UR, "ATI FireGL unknown (R423) UR (PCIE)" },
|
||||
{ PCI_CHIP_R423_UT, "ATI FireGL unknown (R423) UT (PCIE)" },
|
||||
{ PCI_CHIP_RV410_564A, "ATI Mobility FireGL V5000 (M26) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_564B, "ATI Mobility FireGL V5000 (M26) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_564F, "ATI Mobility Radeon X700 XL (M26) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5652, "ATI Mobility Radeon X700 (M26) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5653, "ATI Mobility Radeon X700 (M26) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5657, "ATI Radeon X550XTX 5657 (PCIE)" },
|
||||
{ PCI_CHIP_RS300_5834, "ATI Radeon 9100 IGP (A5) 5834" },
|
||||
{ PCI_CHIP_RS300_5835, "ATI Radeon Mobility 9100 IGP (U3) 5835" },
|
||||
{ PCI_CHIP_RS480_5954, "ATI Radeon XPRESS 200 5954 (PCIE)" },
|
||||
{ PCI_CHIP_RS480_5955, "ATI Radeon XPRESS 200M 5955 (PCIE)" },
|
||||
{ PCI_CHIP_RV280_5960, "ATI Radeon 9250 5960 (AGP)" },
|
||||
{ PCI_CHIP_RV280_5961, "ATI Radeon 9200 5961 (AGP)" },
|
||||
{ PCI_CHIP_RV280_5962, "ATI Radeon 9200 5962 (AGP)" },
|
||||
{ PCI_CHIP_RV280_5964, "ATI Radeon 9200SE 5964 (AGP)" },
|
||||
{ PCI_CHIP_RV280_5965, "ATI FireMV 2200 (PCI)" },
|
||||
{ PCI_CHIP_RN50_5969, "ATI ES1000 5969 (PCI)" },
|
||||
{ PCI_CHIP_RS482_5974, "ATI Radeon XPRESS 200 5974 (PCIE)" },
|
||||
{ PCI_CHIP_RS485_5975, "ATI Radeon XPRESS 200M 5975 (PCIE)" },
|
||||
{ PCI_CHIP_RS400_5A41, "ATI Radeon XPRESS 200 5A41 (PCIE)" },
|
||||
{ PCI_CHIP_RS400_5A42, "ATI Radeon XPRESS 200M 5A42 (PCIE)" },
|
||||
{ PCI_CHIP_RC410_5A61, "ATI Radeon XPRESS 200 5A61 (PCIE)" },
|
||||
{ PCI_CHIP_RC410_5A62, "ATI Radeon XPRESS 200M 5A62 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5B60, "ATI Radeon X300 (RV370) 5B60 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5B62, "ATI Radeon X600 (RV370) 5B62 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5B63, "ATI Radeon X550 (RV370) 5B63 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5B64, "ATI FireGL V3100 (RV370) 5B64 (PCIE)" },
|
||||
{ PCI_CHIP_RV370_5B65, "ATI FireMV 2200 PCIE (RV370) 5B65 (PCIE)" },
|
||||
{ PCI_CHIP_RV280_5C61, "ATI Radeon Mobility 9200 (M9+) 5C61 (AGP)" },
|
||||
{ PCI_CHIP_RV280_5C63, "ATI Radeon Mobility 9200 (M9+) 5C63 (AGP)" },
|
||||
{ PCI_CHIP_R430_5D48, "ATI Mobility Radeon X800 XT (M28) (PCIE)" },
|
||||
{ PCI_CHIP_R430_5D49, "ATI Mobility FireGL V5100 (M28) (PCIE)" },
|
||||
{ PCI_CHIP_R430_5D4A, "ATI Mobility Radeon X800 (M28) (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D4C, "ATI Radeon X850 5D4C (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D4D, "ATI Radeon X850 XT PE (R480) (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D4E, "ATI Radeon X850 SE (R480) (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D4F, "ATI Radeon X850 PRO (R480) (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D50, "ATI unknown Radeon / FireGL (R480) 5D50 (PCIE)" },
|
||||
{ PCI_CHIP_R480_5D52, "ATI Radeon X850 XT (R480) (PCIE)" },
|
||||
{ PCI_CHIP_R423_5D57, "ATI Radeon X800XT (R423) 5D57 (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E48, "ATI FireGL V5000 (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E4A, "ATI Radeon X700 XT (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E4B, "ATI Radeon X700 PRO (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E4C, "ATI Radeon X700 SE (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E4D, "ATI Radeon X700 (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_RV410_5E4F, "ATI Radeon X700 SE (RV410) (PCIE)" },
|
||||
{ PCI_CHIP_R520_7100, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_7101, "ATI Mobility Radeon X1800 XT" },
|
||||
{ PCI_CHIP_R520_7102, "ATI Mobility Radeon X1800" },
|
||||
{ PCI_CHIP_R520_7103, "ATI Mobility FireGL V7200" },
|
||||
{ PCI_CHIP_R520_7104, "ATI FireGL V7200" },
|
||||
{ PCI_CHIP_R520_7105, "ATI FireGL V5300" },
|
||||
{ PCI_CHIP_R520_7106, "ATI Mobility FireGL V7100" },
|
||||
{ PCI_CHIP_R520_7108, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_7109, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_710A, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_710B, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_710C, "ATI Radeon X1800" },
|
||||
{ PCI_CHIP_R520_710E, "ATI FireGL V7300" },
|
||||
{ PCI_CHIP_R520_710F, "ATI FireGL V7350" },
|
||||
{ PCI_CHIP_RV515_7140, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV515_7141, "ATI RV505" },
|
||||
{ PCI_CHIP_RV515_7142, "ATI Radeon X1300/X1550" },
|
||||
{ PCI_CHIP_RV515_7143, "ATI Radeon X1550" },
|
||||
{ PCI_CHIP_RV515_7144, "ATI M54-GL" },
|
||||
{ PCI_CHIP_RV515_7145, "ATI Mobility Radeon X1400" },
|
||||
{ PCI_CHIP_RV515_7146, "ATI Radeon X1300/X1550" },
|
||||
{ PCI_CHIP_RV515_7147, "ATI Radeon X1550 64-bit" },
|
||||
{ PCI_CHIP_RV515_7149, "ATI Mobility Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714A, "ATI Mobility Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714B, "ATI Mobility Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714C, "ATI Mobility Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714D, "ATI Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714E, "ATI Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_714F, "ATI RV505" },
|
||||
{ PCI_CHIP_RV515_7151, "ATI RV505" },
|
||||
{ PCI_CHIP_RV515_7152, "ATI FireGL V3300" },
|
||||
{ PCI_CHIP_RV515_7153, "ATI FireGL V3350" },
|
||||
{ PCI_CHIP_RV515_715E, "ATI Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_715F, "ATI Radeon X1550 64-bit" },
|
||||
{ PCI_CHIP_RV515_7180, "ATI Radeon X1300/X1550" },
|
||||
{ PCI_CHIP_RV515_7181, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV515_7183, "ATI Radeon X1300/X1550" },
|
||||
{ PCI_CHIP_RV515_7186, "ATI Mobility Radeon X1450" },
|
||||
{ PCI_CHIP_RV515_7187, "ATI Radeon X1300/X1550" },
|
||||
{ PCI_CHIP_RV515_7188, "ATI Mobility Radeon X2300" },
|
||||
{ PCI_CHIP_RV515_718A, "ATI Mobility Radeon X2300" },
|
||||
{ PCI_CHIP_RV515_718B, "ATI Mobility Radeon X1350" },
|
||||
{ PCI_CHIP_RV515_718C, "ATI Mobility Radeon X1350" },
|
||||
{ PCI_CHIP_RV515_718D, "ATI Mobility Radeon X1450" },
|
||||
{ PCI_CHIP_RV515_718F, "ATI Radeon X1300" },
|
||||
{ PCI_CHIP_RV515_7193, "ATI Radeon X1550" },
|
||||
{ PCI_CHIP_RV515_7196, "ATI Mobility Radeon X1350" },
|
||||
{ PCI_CHIP_RV515_719B, "ATI FireMV 2250" },
|
||||
{ PCI_CHIP_RV515_719F, "ATI Radeon X1550 64-bit" },
|
||||
{ PCI_CHIP_RV530_71C0, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV530_71C1, "ATI Radeon X1650" },
|
||||
{ PCI_CHIP_RV530_71C2, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV530_71C3, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV530_71C4, "ATI Mobility FireGL V5200" },
|
||||
{ PCI_CHIP_RV530_71C5, "ATI Mobility Radeon X1600" },
|
||||
{ PCI_CHIP_RV530_71C6, "ATI Radeon X1650" },
|
||||
{ PCI_CHIP_RV530_71C7, "ATI Radeon X1650" },
|
||||
{ PCI_CHIP_RV530_71CD, "ATI Radeon X1600" },
|
||||
{ PCI_CHIP_RV530_71CE, "ATI Radeon X1300 XT/X1600 Pro" },
|
||||
{ PCI_CHIP_RV530_71D2, "ATI FireGL V3400" },
|
||||
{ PCI_CHIP_RV530_71D4, "ATI Mobility FireGL V5250" },
|
||||
{ PCI_CHIP_RV530_71D5, "ATI Mobility Radeon X1700" },
|
||||
{ PCI_CHIP_RV530_71D6, "ATI Mobility Radeon X1700 XT" },
|
||||
{ PCI_CHIP_RV530_71DA, "ATI FireGL V5200" },
|
||||
{ PCI_CHIP_RV530_71DE, "ATI Mobility Radeon X1700" },
|
||||
{ PCI_CHIP_RV515_7200, "ATI Radeon X2300HD" },
|
||||
{ PCI_CHIP_RV515_7210, "ATI Mobility Radeon HD 2300" },
|
||||
{ PCI_CHIP_RV515_7211, "ATI Mobility Radeon HD 2300" },
|
||||
{ PCI_CHIP_R580_7240, "ATI Radeon X1950" },
|
||||
{ PCI_CHIP_R580_7243, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_7244, "ATI Radeon X1950" },
|
||||
{ PCI_CHIP_R580_7245, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_7246, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_7247, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_7248, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_7249, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_724A, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_724B, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_724C, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_724D, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_R580_724E, "ATI AMD Stream Processor" },
|
||||
{ PCI_CHIP_R580_724F, "ATI Radeon X1900" },
|
||||
{ PCI_CHIP_RV570_7280, "ATI Radeon X1950" },
|
||||
{ PCI_CHIP_RV560_7281, "ATI RV560" },
|
||||
{ PCI_CHIP_RV560_7283, "ATI RV560" },
|
||||
{ PCI_CHIP_R580_7284, "ATI Mobility Radeon X1900" },
|
||||
{ PCI_CHIP_RV560_7287, "ATI RV560" },
|
||||
{ PCI_CHIP_RV570_7288, "ATI Radeon X1950 GT" },
|
||||
{ PCI_CHIP_RV570_7289, "ATI RV570" },
|
||||
{ PCI_CHIP_RV570_728B, "ATI RV570" },
|
||||
{ PCI_CHIP_RV570_728C, "ATI ATI FireGL V7400" },
|
||||
{ PCI_CHIP_RV560_7290, "ATI RV560" },
|
||||
{ PCI_CHIP_RV560_7291, "ATI Radeon X1650" },
|
||||
{ PCI_CHIP_RV560_7293, "ATI Radeon X1650" },
|
||||
{ PCI_CHIP_RV560_7297, "ATI RV560" },
|
||||
{ PCI_CHIP_RS350_7834, "ATI Radeon 9100 PRO IGP 7834" },
|
||||
{ PCI_CHIP_RS350_7835, "ATI Radeon Mobility 9200 IGP 7835" },
|
||||
{ PCI_CHIP_RS690_791E, "ATI Radeon X1200" },
|
||||
{ PCI_CHIP_RS690_791F, "ATI Radeon X1200" },
|
||||
{ PCI_CHIP_RS600_793F, "ATI Radeon X1200" },
|
||||
{ PCI_CHIP_RS600_7941, "ATI Radeon X1200" },
|
||||
{ PCI_CHIP_RS600_7942, "ATI Radeon X1200" },
|
||||
{ PCI_CHIP_RS740_796C, "ATI RS740" },
|
||||
{ PCI_CHIP_RS740_796D, "ATI RS740M" },
|
||||
{ PCI_CHIP_RS740_796E, "ATI RS740" },
|
||||
{ PCI_CHIP_RS740_796F, "ATI RS740M" },
|
||||
{ PCI_CHIP_R600_9400, "ATI Radeon HD 2900 XT" },
|
||||
{ PCI_CHIP_R600_9401, "ATI Radeon HD 2900 XT" },
|
||||
{ PCI_CHIP_R600_9402, "ATI Radeon HD 2900 XT" },
|
||||
{ PCI_CHIP_R600_9403, "ATI Radeon HD 2900 Pro" },
|
||||
{ PCI_CHIP_R600_9405, "ATI Radeon HD 2900 GT" },
|
||||
{ PCI_CHIP_R600_940A, "ATI FireGL V8650" },
|
||||
{ PCI_CHIP_R600_940B, "ATI FireGL V8600" },
|
||||
{ PCI_CHIP_R600_940F, "ATI FireGL V7600" },
|
||||
{ PCI_CHIP_RV770_9440, "ATI Radeon 4800 Series" },
|
||||
{ PCI_CHIP_RV770_9441, "ATI Radeon HD 4870 x2" },
|
||||
{ PCI_CHIP_RV770_9442, "ATI Radeon 4800 Series" },
|
||||
{ PCI_CHIP_RV610_94C0, "ATI RV610" },
|
||||
{ PCI_CHIP_RV610_94C1, "ATI Radeon HD 2400 XT" },
|
||||
{ PCI_CHIP_RV610_94C3, "ATI Radeon HD 2400 Pro" },
|
||||
{ PCI_CHIP_RV610_94C4, "ATI Radeon HD 2400 PRO AGP" },
|
||||
{ PCI_CHIP_RV610_94C5, "ATI FireGL V4000" },
|
||||
{ PCI_CHIP_RV610_94C6, "ATI RV610" },
|
||||
{ PCI_CHIP_RV610_94C7, "ATI ATI Radeon HD 2350" },
|
||||
{ PCI_CHIP_RV610_94C8, "ATI Mobility Radeon HD 2400 XT" },
|
||||
{ PCI_CHIP_RV610_94C9, "ATI Mobility Radeon HD 2400" },
|
||||
{ PCI_CHIP_RV610_94CB, "ATI RADEON E2400" },
|
||||
{ PCI_CHIP_RV610_94CC, "ATI RV610" },
|
||||
{ PCI_CHIP_RV670_9500, "ATI RV670" },
|
||||
{ PCI_CHIP_RV670_9501, "ATI Radeon HD3870" },
|
||||
{ PCI_CHIP_RV670_9505, "ATI Radeon HD3850" },
|
||||
{ PCI_CHIP_RV670_9507, "ATI RV670" },
|
||||
{ PCI_CHIP_RV670_950F, "ATI Radeon HD3870 X2" },
|
||||
{ PCI_CHIP_RV670_9511, "ATI FireGL V7700" },
|
||||
{ PCI_CHIP_RV670_9515, "ATI Radeon HD3850" },
|
||||
{ PCI_CHIP_RV630_9580, "ATI RV630" },
|
||||
{ PCI_CHIP_RV630_9581, "ATI Mobility Radeon HD 2600" },
|
||||
{ PCI_CHIP_RV630_9583, "ATI Mobility Radeon HD 2600 XT" },
|
||||
{ PCI_CHIP_RV630_9586, "ATI Radeon HD 2600 XT AGP" },
|
||||
{ PCI_CHIP_RV630_9587, "ATI Radeon HD 2600 Pro AGP" },
|
||||
{ PCI_CHIP_RV630_9588, "ATI Radeon HD 2600 XT" },
|
||||
{ PCI_CHIP_RV630_9589, "ATI Radeon HD 2600 Pro" },
|
||||
{ PCI_CHIP_RV630_958A, "ATI Gemini RV630" },
|
||||
{ PCI_CHIP_RV630_958B, "ATI Gemini Mobility Radeon HD 2600 XT" },
|
||||
{ PCI_CHIP_RV630_958C, "ATI FireGL V5600" },
|
||||
{ PCI_CHIP_RV630_958D, "ATI FireGL V3600" },
|
||||
{ PCI_CHIP_RV630_958E, "ATI Radeon HD 2600 LE" },
|
||||
{ PCI_CHIP_RV620_95C0, "ATI Radeon HD 3470" },
|
||||
{ PCI_CHIP_RV620_95C5, "ATI Radeon HD 3450" },
|
||||
{ PCI_CHIP_RV620_95C7, "ATI Radeon HD 3430" },
|
||||
{ PCI_CHIP_RV620_95C2, "ATI Mobility Radeon HD 3430" },
|
||||
{ PCI_CHIP_RV620_95C4, "ATI Mobility Radeon HD 3400 Series" },
|
||||
{ PCI_CHIP_RV620_95CD, "ATI FireMV 2450" },
|
||||
{ PCI_CHIP_RV620_95CE, "ATI FireMV 2260" },
|
||||
{ PCI_CHIP_RV620_95CF, "ATI FireMV 2260" },
|
||||
{ PCI_CHIP_RV635_9590, "ATI ATI Radeon HD 3600 Series" },
|
||||
{ PCI_CHIP_RV635_9596, "ATI ATI Radeon HD 3650 AGP" },
|
||||
{ PCI_CHIP_RV635_9597, "ATI ATI Radeon HD 3600 PRO" },
|
||||
{ PCI_CHIP_RV635_9598, "ATI ATI Radeon HD 3600 XT" },
|
||||
{ PCI_CHIP_RV635_9599, "ATI ATI Radeon HD 3600 PRO" },
|
||||
{ PCI_CHIP_RV635_9591, "ATI Mobility Radeon HD 3650" },
|
||||
{ PCI_CHIP_RV635_9593, "ATI Mobility Radeon HD 3670" },
|
||||
{ PCI_CHIP_RS780_9610, "ATI Radeon HD 3200 Graphics" },
|
||||
{ PCI_CHIP_RS780_9611, "ATI Radeon 3100 Graphics" },
|
||||
{ PCI_CHIP_RS780_9612, "ATI Radeon HD 3200 Graphics" },
|
||||
{ PCI_CHIP_RS780_9613, "ATI Radeon 3100 Graphics" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
1844
drivers/video/ati2d/radeon_microcode.h
Normal file
1844
drivers/video/ati2d/radeon_microcode.h
Normal file
File diff suppressed because it is too large
Load Diff
5322
drivers/video/ati2d/radeon_reg.h
Normal file
5322
drivers/video/ati2d/radeon_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
836
drivers/video/ati2d/rhd_regs.h
Normal file
836
drivers/video/ati2d/rhd_regs.h
Normal file
@@ -0,0 +1,836 @@
|
||||
/*
|
||||
* Copyright 2007, 2008 Luc Verhaegen <lverhaegen@novell.com>
|
||||
* Copyright 2007, 2008 Matthias Hopf <mhopf@novell.com>
|
||||
* Copyright 2007, 2008 Egbert Eich <eich@novell.com>
|
||||
* Copyright 2007, 2008 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.
|
||||
*/
|
||||
#ifndef _RHD_REGS_H
|
||||
# define _RHD_REGS_H
|
||||
|
||||
enum {
|
||||
CLOCK_CNTL_INDEX = 0x8, /* (RW) */
|
||||
CLOCK_CNTL_DATA = 0xC, /* (RW) */
|
||||
BUS_CNTL = 0x4C, /* (RW) */
|
||||
MC_IND_INDEX = 0x70, /* (RW) */
|
||||
MC_IND_DATA = 0x74, /* (RW) */
|
||||
CONFIG_CNTL = 0xE0,
|
||||
/* RS690 ?? */
|
||||
RS69_MC_INDEX = 0xE8,
|
||||
RS69_MC_DATA = 0xEC,
|
||||
R5XX_CONFIG_MEMSIZE = 0x00F8,
|
||||
|
||||
HDP_FB_LOCATION = 0x0134,
|
||||
|
||||
SEPROM_CNTL1 = 0x1C0, /* (RW) */
|
||||
GPIOPAD_MASK = 0x198, /* (RW) */
|
||||
GPIOPAD_A = 0x19C, /* (RW) */
|
||||
GPIOPAD_EN = 0x1A0, /* (RW) */
|
||||
VIPH_CONTROL = 0xC40, /* (RW) */
|
||||
|
||||
/* VGA registers */
|
||||
VGA_RENDER_CONTROL = 0x0300,
|
||||
VGA_MODE_CONTROL = 0x0308,
|
||||
VGA_MEMORY_BASE_ADDRESS = 0x0310,
|
||||
VGA_HDP_CONTROL = 0x0328,
|
||||
D1VGA_CONTROL = 0x0330,
|
||||
D2VGA_CONTROL = 0x0338,
|
||||
|
||||
EXT1_PPLL_REF_DIV_SRC = 0x0400,
|
||||
EXT1_PPLL_REF_DIV = 0x0404,
|
||||
EXT1_PPLL_UPDATE_LOCK = 0x0408,
|
||||
EXT1_PPLL_UPDATE_CNTL = 0x040C,
|
||||
EXT2_PPLL_REF_DIV_SRC = 0x0410,
|
||||
EXT2_PPLL_REF_DIV = 0x0414,
|
||||
EXT2_PPLL_UPDATE_LOCK = 0x0418,
|
||||
EXT2_PPLL_UPDATE_CNTL = 0x041C,
|
||||
|
||||
EXT1_PPLL_FB_DIV = 0x0430,
|
||||
EXT2_PPLL_FB_DIV = 0x0434,
|
||||
EXT1_PPLL_POST_DIV_SRC = 0x0438,
|
||||
EXT1_PPLL_POST_DIV = 0x043C,
|
||||
EXT2_PPLL_POST_DIV_SRC = 0x0440,
|
||||
EXT2_PPLL_POST_DIV = 0x0444,
|
||||
EXT1_PPLL_CNTL = 0x0448,
|
||||
EXT2_PPLL_CNTL = 0x044C,
|
||||
P1PLL_CNTL = 0x0450,
|
||||
P2PLL_CNTL = 0x0454,
|
||||
P1PLL_INT_SS_CNTL = 0x0458,
|
||||
P2PLL_INT_SS_CNTL = 0x045C,
|
||||
|
||||
P1PLL_DISP_CLK_CNTL = 0x0468, /* rv620+ */
|
||||
P2PLL_DISP_CLK_CNTL = 0x046C, /* rv620+ */
|
||||
EXT1_SYM_PPLL_POST_DIV = 0x0470, /* rv620+ */
|
||||
EXT2_SYM_PPLL_POST_DIV = 0x0474, /* rv620+ */
|
||||
|
||||
PCLK_CRTC1_CNTL = 0x0480,
|
||||
PCLK_CRTC2_CNTL = 0x0484,
|
||||
|
||||
DCCG_DISP_CLK_SRCSEL = 0x0538, /* rv620+ */
|
||||
|
||||
R6XX_MC_VM_FB_LOCATION = 0x2180,
|
||||
R6XX_HDP_NONSURFACE_BASE = 0x2C04,
|
||||
R6XX_CONFIG_MEMSIZE = 0x5428,
|
||||
R6XX_CONFIG_FB_BASE = 0x542C, /* AKA CONFIG_F0_BASE */
|
||||
|
||||
/* CRTC1 registers */
|
||||
D1CRTC_H_TOTAL = 0x6000,
|
||||
D1CRTC_H_BLANK_START_END = 0x6004,
|
||||
D1CRTC_H_SYNC_A = 0x6008,
|
||||
D1CRTC_H_SYNC_A_CNTL = 0x600C,
|
||||
D1CRTC_H_SYNC_B = 0x6010,
|
||||
D1CRTC_H_SYNC_B_CNTL = 0x6014,
|
||||
|
||||
D1CRTC_V_TOTAL = 0x6020,
|
||||
D1CRTC_V_BLANK_START_END = 0x6024,
|
||||
D1CRTC_V_SYNC_A = 0x6028,
|
||||
D1CRTC_V_SYNC_A_CNTL = 0x602C,
|
||||
D1CRTC_V_SYNC_B = 0x6030,
|
||||
D1CRTC_V_SYNC_B_CNTL = 0x6034,
|
||||
|
||||
D1CRTC_CONTROL = 0x6080,
|
||||
D1CRTC_BLANK_CONTROL = 0x6084,
|
||||
D1CRTC_INTERLACE_CONTROL = 0x6088,
|
||||
D1CRTC_BLACK_COLOR = 0x6098,
|
||||
D1CRTC_STATUS = 0x609C,
|
||||
D1CRTC_COUNT_CONTROL = 0x60B4,
|
||||
|
||||
/* D1GRPH registers */
|
||||
D1GRPH_ENABLE = 0x6100,
|
||||
D1GRPH_CONTROL = 0x6104,
|
||||
D1GRPH_LUT_SEL = 0x6108,
|
||||
D1GRPH_SWAP_CNTL = 0x610C,
|
||||
D1GRPH_PRIMARY_SURFACE_ADDRESS = 0x6110,
|
||||
D1GRPH_SECONDARY_SURFACE_ADDRESS = 0x6118,
|
||||
D1GRPH_PITCH = 0x6120,
|
||||
D1GRPH_SURFACE_OFFSET_X = 0x6124,
|
||||
D1GRPH_SURFACE_OFFSET_Y = 0x6128,
|
||||
D1GRPH_X_START = 0x612C,
|
||||
D1GRPH_Y_START = 0x6130,
|
||||
D1GRPH_X_END = 0x6134,
|
||||
D1GRPH_Y_END = 0x6138,
|
||||
D1GRPH_UPDATE = 0x6144,
|
||||
|
||||
/* LUT */
|
||||
DC_LUT_RW_SELECT = 0x6480,
|
||||
DC_LUT_RW_MODE = 0x6484,
|
||||
DC_LUT_RW_INDEX = 0x6488,
|
||||
DC_LUT_SEQ_COLOR = 0x648C,
|
||||
DC_LUT_PWL_DATA = 0x6490,
|
||||
DC_LUT_30_COLOR = 0x6494,
|
||||
DC_LUT_READ_PIPE_SELECT = 0x6498,
|
||||
DC_LUT_WRITE_EN_MASK = 0x649C,
|
||||
DC_LUT_AUTOFILL = 0x64A0,
|
||||
|
||||
/* LUTA */
|
||||
DC_LUTA_CONTROL = 0x64C0,
|
||||
DC_LUTA_BLACK_OFFSET_BLUE = 0x64C4,
|
||||
DC_LUTA_BLACK_OFFSET_GREEN = 0x64C8,
|
||||
DC_LUTA_BLACK_OFFSET_RED = 0x64CC,
|
||||
DC_LUTA_WHITE_OFFSET_BLUE = 0x64D0,
|
||||
DC_LUTA_WHITE_OFFSET_GREEN = 0x64D4,
|
||||
DC_LUTA_WHITE_OFFSET_RED = 0x64D8,
|
||||
|
||||
/* D1CUR */
|
||||
D1CUR_CONTROL = 0x6400,
|
||||
D1CUR_SURFACE_ADDRESS = 0x6408,
|
||||
D1CUR_SIZE = 0x6410,
|
||||
D1CUR_POSITION = 0x6414,
|
||||
D1CUR_HOT_SPOT = 0x6418,
|
||||
D1CUR_UPDATE = 0x6424,
|
||||
|
||||
/* D1MODE */
|
||||
D1MODE_DESKTOP_HEIGHT = 0x652C,
|
||||
D1MODE_VIEWPORT_START = 0x6580,
|
||||
D1MODE_VIEWPORT_SIZE = 0x6584,
|
||||
D1MODE_EXT_OVERSCAN_LEFT_RIGHT = 0x6588,
|
||||
D1MODE_EXT_OVERSCAN_TOP_BOTTOM = 0x658C,
|
||||
D1MODE_DATA_FORMAT = 0x6528,
|
||||
|
||||
/* D1SCL */
|
||||
D1SCL_ENABLE = 0x6590,
|
||||
D1SCL_TAP_CONTROL = 0x6594,
|
||||
D1MODE_CENTER = 0x659C, /* guess */
|
||||
D1SCL_HVSCALE = 0x65A4, /* guess */
|
||||
D1SCL_HFILTER = 0x65B0, /* guess */
|
||||
D1SCL_VFILTER = 0x65C0, /* guess */
|
||||
D1SCL_UPDATE = 0x65CC,
|
||||
D1SCL_DITHER = 0x65D4, /* guess */
|
||||
D1SCL_FLIP_CONTROL = 0x65D8, /* guess */
|
||||
|
||||
/* CRTC2 registers */
|
||||
D2CRTC_H_TOTAL = 0x6800,
|
||||
D2CRTC_H_BLANK_START_END = 0x6804,
|
||||
D2CRTC_H_SYNC_A = 0x6808,
|
||||
D2CRTC_H_SYNC_A_CNTL = 0x680C,
|
||||
D2CRTC_H_SYNC_B = 0x6810,
|
||||
D2CRTC_H_SYNC_B_CNTL = 0x6814,
|
||||
|
||||
D2CRTC_V_TOTAL = 0x6820,
|
||||
D2CRTC_V_BLANK_START_END = 0x6824,
|
||||
D2CRTC_V_SYNC_A = 0x6828,
|
||||
D2CRTC_V_SYNC_A_CNTL = 0x682C,
|
||||
D2CRTC_V_SYNC_B = 0x6830,
|
||||
D2CRTC_V_SYNC_B_CNTL = 0x6834,
|
||||
|
||||
D2CRTC_CONTROL = 0x6880,
|
||||
D2CRTC_BLANK_CONTROL = 0x6884,
|
||||
D2CRTC_BLACK_COLOR = 0x6898,
|
||||
D2CRTC_INTERLACE_CONTROL = 0x6888,
|
||||
D2CRTC_STATUS = 0x689C,
|
||||
D2CRTC_COUNT_CONTROL = 0x68B4,
|
||||
|
||||
/* D2GRPH registers */
|
||||
D2GRPH_ENABLE = 0x6900,
|
||||
D2GRPH_CONTROL = 0x6904,
|
||||
D2GRPH_LUT_SEL = 0x6908,
|
||||
D2GRPH_SWAP_CNTL = 0x690C,
|
||||
D2GRPH_PRIMARY_SURFACE_ADDRESS = 0x6910,
|
||||
D2GRPH_PITCH = 0x6920,
|
||||
D2GRPH_SURFACE_OFFSET_X = 0x6924,
|
||||
D2GRPH_SURFACE_OFFSET_Y = 0x6928,
|
||||
D2GRPH_X_START = 0x692C,
|
||||
D2GRPH_Y_START = 0x6930,
|
||||
D2GRPH_X_END = 0x6934,
|
||||
D2GRPH_Y_END = 0x6938,
|
||||
|
||||
/* LUTB */
|
||||
DC_LUTB_CONTROL = 0x6CC0,
|
||||
DC_LUTB_BLACK_OFFSET_BLUE = 0x6CC4,
|
||||
DC_LUTB_BLACK_OFFSET_GREEN = 0x6CC8,
|
||||
DC_LUTB_BLACK_OFFSET_RED = 0x6CCC,
|
||||
DC_LUTB_WHITE_OFFSET_BLUE = 0x6CD0,
|
||||
DC_LUTB_WHITE_OFFSET_GREEN = 0x6CD4,
|
||||
DC_LUTB_WHITE_OFFSET_RED = 0x6CD8,
|
||||
|
||||
/* D2MODE */
|
||||
D2MODE_DESKTOP_HEIGHT = 0x6D2C,
|
||||
D2MODE_VIEWPORT_START = 0x6D80,
|
||||
D2MODE_VIEWPORT_SIZE = 0x6D84,
|
||||
D2MODE_EXT_OVERSCAN_LEFT_RIGHT = 0x6D88,
|
||||
D2MODE_EXT_OVERSCAN_TOP_BOTTOM = 0x6D8C,
|
||||
D2MODE_DATA_FORMAT = 0x6D28,
|
||||
|
||||
/* D2SCL */
|
||||
D2SCL_ENABLE = 0x6D90,
|
||||
D2SCL_TAP_CONTROL = 0x6D94,
|
||||
D2MODE_CENTER = 0x6D9C, /* guess */
|
||||
D2SCL_HVSCALE = 0x6DA4, /* guess */
|
||||
D2SCL_HFILTER = 0x6DB0, /* guess */
|
||||
D2SCL_VFILTER = 0x6DC0, /* guess */
|
||||
D2SCL_UPDATE = 0x6DCC,
|
||||
D2SCL_DITHER = 0x6DD4, /* guess */
|
||||
D2SCL_FLIP_CONTROL = 0x6DD8, /* guess */
|
||||
|
||||
/* R500 DAC A */
|
||||
DACA_ENABLE = 0x7800,
|
||||
DACA_SOURCE_SELECT = 0x7804,
|
||||
DACA_SYNC_TRISTATE_CONTROL = 0x7820,
|
||||
DACA_SYNC_SELECT = 0x7824,
|
||||
DACA_AUTODETECT_CONTROL = 0x7828,
|
||||
DACA_FORCE_OUTPUT_CNTL = 0x783C,
|
||||
DACA_FORCE_DATA = 0x7840,
|
||||
DACA_POWERDOWN = 0x7850,
|
||||
DACA_CONTROL1 = 0x7854,
|
||||
DACA_CONTROL2 = 0x7858,
|
||||
DACA_COMPARATOR_ENABLE = 0x785C,
|
||||
DACA_COMPARATOR_OUTPUT = 0x7860,
|
||||
|
||||
/* TMDSA */
|
||||
TMDSA_CNTL = 0x7880,
|
||||
TMDSA_SOURCE_SELECT = 0x7884,
|
||||
TMDSA_COLOR_FORMAT = 0x7888,
|
||||
TMDSA_FORCE_OUTPUT_CNTL = 0x788C,
|
||||
TMDSA_BIT_DEPTH_CONTROL = 0x7894,
|
||||
TMDSA_DCBALANCER_CONTROL = 0x78D0,
|
||||
TMDSA_DATA_SYNCHRONIZATION_R500 = 0x78D8,
|
||||
TMDSA_DATA_SYNCHRONIZATION_R600 = 0x78DC,
|
||||
TMDSA_TRANSMITTER_ENABLE = 0x7904,
|
||||
TMDSA_LOAD_DETECT = 0x7908,
|
||||
TMDSA_MACRO_CONTROL = 0x790C, /* r5x0 and r600: 3 for pll and 1 for TX */
|
||||
TMDSA_PLL_ADJUST = 0x790C, /* rv6x0: pll only */
|
||||
TMDSA_TRANSMITTER_CONTROL = 0x7910,
|
||||
TMDSA_TRANSMITTER_ADJUST = 0x7920, /* rv6x0: TX part of macro control */
|
||||
|
||||
/* DAC B */
|
||||
DACB_ENABLE = 0x7A00,
|
||||
DACB_SOURCE_SELECT = 0x7A04,
|
||||
DACB_SYNC_TRISTATE_CONTROL = 0x7A20,
|
||||
DACB_SYNC_SELECT = 0x7A24,
|
||||
DACB_AUTODETECT_CONTROL = 0x7A28,
|
||||
DACB_FORCE_OUTPUT_CNTL = 0x7A3C,
|
||||
DACB_FORCE_DATA = 0x7A40,
|
||||
DACB_POWERDOWN = 0x7A50,
|
||||
DACB_CONTROL1 = 0x7A54,
|
||||
DACB_CONTROL2 = 0x7A58,
|
||||
DACB_COMPARATOR_ENABLE = 0x7A5C,
|
||||
DACB_COMPARATOR_OUTPUT = 0x7A60,
|
||||
|
||||
/* LVTMA */
|
||||
LVTMA_CNTL = 0x7A80,
|
||||
LVTMA_SOURCE_SELECT = 0x7A84,
|
||||
LVTMA_COLOR_FORMAT = 0x7A88,
|
||||
LVTMA_FORCE_OUTPUT_CNTL = 0x7A8C,
|
||||
LVTMA_BIT_DEPTH_CONTROL = 0x7A94,
|
||||
LVTMA_DCBALANCER_CONTROL = 0x7AD0,
|
||||
|
||||
/* no longer shared between both r5xx and r6xx */
|
||||
LVTMA_R500_DATA_SYNCHRONIZATION = 0x7AD8,
|
||||
LVTMA_R500_PWRSEQ_REF_DIV = 0x7AE4,
|
||||
LVTMA_R500_PWRSEQ_DELAY1 = 0x7AE8,
|
||||
LVTMA_R500_PWRSEQ_DELAY2 = 0x7AEC,
|
||||
LVTMA_R500_PWRSEQ_CNTL = 0x7AF0,
|
||||
LVTMA_R500_PWRSEQ_STATE = 0x7AF4,
|
||||
LVTMA_R500_LVDS_DATA_CNTL = 0x7AFC,
|
||||
LVTMA_R500_MODE = 0x7B00,
|
||||
LVTMA_R500_TRANSMITTER_ENABLE = 0x7B04,
|
||||
LVTMA_R500_MACRO_CONTROL = 0x7B0C,
|
||||
LVTMA_R500_TRANSMITTER_CONTROL = 0x7B10,
|
||||
LVTMA_R500_REG_TEST_OUTPUT = 0x7B14,
|
||||
|
||||
/* R600 adds an undocumented register at 0x7AD8,
|
||||
* shifting all subsequent registers by exactly one. */
|
||||
LVTMA_R600_DATA_SYNCHRONIZATION = 0x7ADC,
|
||||
LVTMA_R600_PWRSEQ_REF_DIV = 0x7AE8,
|
||||
LVTMA_R600_PWRSEQ_DELAY1 = 0x7AEC,
|
||||
LVTMA_R600_PWRSEQ_DELAY2 = 0x7AF0,
|
||||
LVTMA_R600_PWRSEQ_CNTL = 0x7AF4,
|
||||
LVTMA_R600_PWRSEQ_STATE = 0x7AF8,
|
||||
LVTMA_R600_LVDS_DATA_CNTL = 0x7B00,
|
||||
LVTMA_R600_MODE = 0x7B04,
|
||||
LVTMA_R600_TRANSMITTER_ENABLE = 0x7B08,
|
||||
LVTMA_R600_MACRO_CONTROL = 0x7B10,
|
||||
LVTMA_R600_TRANSMITTER_CONTROL = 0x7B14,
|
||||
LVTMA_R600_REG_TEST_OUTPUT = 0x7B18,
|
||||
|
||||
LVTMA_TRANSMITTER_ADJUST = 0x7B24, /* RV630 */
|
||||
LVTMA_PREEMPHASIS_CONTROL = 0x7B28, /* RV630 */
|
||||
|
||||
/* I2C in separate enum */
|
||||
|
||||
/* HPD */
|
||||
DC_GPIO_HPD_MASK = 0x7E90,
|
||||
DC_GPIO_HPD_A = 0x7E94,
|
||||
DC_GPIO_HPD_EN = 0x7E98,
|
||||
DC_GPIO_HPD_Y = 0x7E9C
|
||||
};
|
||||
|
||||
enum CONFIG_CNTL_BITS {
|
||||
RS69_CFG_ATI_REV_ID_SHIFT = 8,
|
||||
RS69_CFG_ATI_REV_ID_MASK = 0xF << RS69_CFG_ATI_REV_ID_SHIFT
|
||||
};
|
||||
|
||||
enum rv620Regs {
|
||||
/* DAC common */
|
||||
RV620_DAC_COMPARATOR_MISC = 0x7da4,
|
||||
RV620_DAC_COMPARATOR_OUTPUT = 0x7da8,
|
||||
|
||||
/* RV620 DAC A */
|
||||
RV620_DACA_ENABLE = 0x7000,
|
||||
RV620_DACA_SOURCE_SELECT = 0x7004,
|
||||
RV620_DACA_SYNC_TRISTATE_CONTROL = 0x7020,
|
||||
/* RV620_DACA_SYNC_SELECT = 0x7024, ?? */
|
||||
RV620_DACA_AUTODETECT_CONTROL = 0x7028,
|
||||
RV620_DACA_AUTODETECT_STATUS = 0x7034,
|
||||
RV620_DACA_AUTODETECT_INT_CONTROL = 0x7038,
|
||||
RV620_DACA_FORCE_OUTPUT_CNTL = 0x703C,
|
||||
RV620_DACA_FORCE_DATA = 0x7040,
|
||||
RV620_DACA_POWERDOWN = 0x7050,
|
||||
/* RV620_DACA_CONTROL1 moved */
|
||||
RV620_DACA_CONTROL2 = 0x7058,
|
||||
RV620_DACA_COMPARATOR_ENABLE = 0x705C,
|
||||
/* RV620_DACA_COMPARATOR_OUTPUT changed */
|
||||
RV620_DACA_BGADJ_SRC = 0x7ef0,
|
||||
RV620_DACA_MACRO_CNTL = 0x7ef4,
|
||||
RV620_DACA_AUTO_CALIB_CONTROL = 0x7ef8,
|
||||
|
||||
/* DAC B */
|
||||
RV620_DACB_ENABLE = 0x7100,
|
||||
RV620_DACB_SOURCE_SELECT = 0x7104,
|
||||
RV620_DACB_SYNC_TRISTATE_CONTROL = 0x7120,
|
||||
/* RV620_DACB_SYNC_SELECT = 0x7124, ?? */
|
||||
RV620_DACB_AUTODETECT_CONTROL = 0x7128,
|
||||
RV620_DACB_AUTODETECT_STATUS = 0x7134,
|
||||
RV620_DACB_AUTODETECT_INT_CONTROL = 0x7138,
|
||||
RV620_DACB_FORCE_OUTPUT_CNTL = 0x713C,
|
||||
RV620_DACB_FORCE_DATA = 0x7140,
|
||||
RV620_DACB_POWERDOWN = 0x7150,
|
||||
/* RV620_DACB_CONTROL1 moved */
|
||||
RV620_DACB_CONTROL2 = 0x7158,
|
||||
RV620_DACB_COMPARATOR_ENABLE = 0x715C,
|
||||
RV620_DACB_BGADJ_SRC = 0x7ef0,
|
||||
RV620_DACB_MACRO_CNTL = 0x7ff4,
|
||||
RV620_DACB_AUTO_CALIB_CONTROL = 0x7ef8,
|
||||
/* DIG1 */
|
||||
RV620_DIG1_CNTL = 0x75A0,
|
||||
RV620_DIG1_CLOCK_PATTERN = 0x75AC,
|
||||
RV620_LVDS1_DATA_CNTL = 0x75BC,
|
||||
RV620_TMDS1_CNTL = 0x75C0,
|
||||
/* DIG2 */
|
||||
RV620_DIG2_CNTL = 0x79A0,
|
||||
RV620_DIG2_CLOCK_PATTERN = 0x79AC,
|
||||
RV620_LVDS2_DATA_CNTL = 0x79BC,
|
||||
RV620_TMDS2_CNTL = 0x79C0,
|
||||
|
||||
/* RV62x I2C */
|
||||
RV62_GENERIC_I2C_CONTROL = 0x7d80, /* (RW) */
|
||||
RV62_GENERIC_I2C_INTERRUPT_CONTROL = 0x7d84, /* (RW) */
|
||||
RV62_GENERIC_I2C_STATUS = 0x7d88, /* (RW) */
|
||||
RV62_GENERIC_I2C_SPEED = 0x7d8c, /* (RW) */
|
||||
RV62_GENERIC_I2C_SETUP = 0x7d90, /* (RW) */
|
||||
RV62_GENERIC_I2C_TRANSACTION = 0x7d94, /* (RW) */
|
||||
RV62_GENERIC_I2C_DATA = 0x7d98, /* (RW) */
|
||||
RV62_GENERIC_I2C_PIN_SELECTION = 0x7d9c, /* (RW) */
|
||||
RV62_DC_GPIO_DDC4_MASK = 0x7e20, /* (RW) */
|
||||
RV62_DC_GPIO_DDC1_MASK = 0x7e40, /* (RW) */
|
||||
RV62_DC_GPIO_DDC2_MASK = 0x7e50, /* (RW) */
|
||||
RV62_DC_GPIO_DDC3_MASK = 0x7e60, /* (RW) */
|
||||
|
||||
/* ?? */
|
||||
RV620_DCIO_LINK_STEER_CNTL = 0x7FA4,
|
||||
|
||||
RV620_LVTMA_TRANSMITTER_CONTROL= 0x7F00,
|
||||
RV620_LVTMA_TRANSMITTER_ENABLE = 0x7F04,
|
||||
RV620_LVTMA_TRANSMITTER_ADJUST = 0x7F18,
|
||||
RV620_LVTMA_PREEMPHASIS_CONTROL= 0x7F1C,
|
||||
RV620_LVTMA_MACRO_CONTROL = 0x7F0C,
|
||||
RV620_LVTMA_DATA_SYNCHRONIZATION = 0x7F98,
|
||||
|
||||
RV620_FMT1_CONTROL = 0x6700,
|
||||
RV620_FMT1_BIT_DEPTH_CONTROL= 0x6710,
|
||||
RV620_FMT1_CLAMP_CNTL = 0x672C,
|
||||
RV620_FMT2_CONTROL = 0x6F00,
|
||||
RV620_FMT2_CNTL = 0x6F10,
|
||||
RV620_FMT2_CLAMP_CNTL = 0x6F2C,
|
||||
|
||||
RV620_DCCG_PCLK_DIGA_CNTL = 0x04b0,
|
||||
RV620_DCCG_PCLK_DIGB_CNTL = 0x04b4,
|
||||
RV620_DCCG_SYMCLK_CNTL = 0x04b8
|
||||
};
|
||||
|
||||
enum RV620_LVTMA_TRANSMITTER_CONTROL_BITS {
|
||||
RV62_LVTMA_PLL_ENABLE = 1 << 0,
|
||||
RV62_LVTMA_PLL_RESET = 1 << 1,
|
||||
RV62_LVTMA_IDSCKSEL = 1 << 4,
|
||||
RV62_LVTMA_BGSLEEP = 1 << 5,
|
||||
RV62_LVTMA_IDCLK_SEL = 1 << 6,
|
||||
RV62_LVTMA_TMCLK = 1 << 8,
|
||||
RV62_LVTMA_TMCLK_FROM_PADS = 1 << 13,
|
||||
RV62_LVTMA_TDCLK = 1 << 14,
|
||||
RV62_LVTMA_TDCLK_FROM_PADS = 1 << 15,
|
||||
RV62_LVTMA_BYPASS_PLL = 1 << 28,
|
||||
RV62_LVTMA_USE_CLK_DATA = 1 << 29,
|
||||
RV62_LVTMA_MODE = 1 << 30,
|
||||
RV62_LVTMA_INPUT_TEST_CLK_SEL = 1 << 31
|
||||
};
|
||||
|
||||
enum RV620_DCCG_SYMCLK_CNTL {
|
||||
RV62_SYMCLKA_SRC_SHIFT = 8,
|
||||
RV62_SYMCLKB_SRC_SHIFT = 12
|
||||
};
|
||||
|
||||
enum RV620_DCCG_DIG_CNTL {
|
||||
RV62_PCLK_DIGA_ON = 0x1
|
||||
};
|
||||
|
||||
enum RV620_DCIO_LINK_STEER_CNTL {
|
||||
RV62_LINK_STEER_SWAP = 1 << 0,
|
||||
RV62_LINK_STEER_PLLSEL_OVERWRITE_EN = 1 << 16,
|
||||
RV62_LINK_STEER_PLLSELA = 1 << 17,
|
||||
RV62_LINK_STEER_PLLSELB = 1 << 18
|
||||
};
|
||||
|
||||
enum R620_LVTMA_TRANSMITTER_ENABLE_BITS {
|
||||
RV62_LVTMA_LNK0EN = 1 << 0,
|
||||
RV62_LVTMA_LNK1EN = 1 << 1,
|
||||
RV62_LVTMA_LNK2EN = 1 << 2,
|
||||
RV62_LVTMA_LNK3EN = 1 << 3,
|
||||
RV62_LVTMA_LNK4EN = 1 << 4,
|
||||
RV62_LVTMA_LNK5EN = 1 << 5,
|
||||
RV62_LVTMA_LNK6EN = 1 << 6,
|
||||
RV62_LVTMA_LNK7EN = 1 << 7,
|
||||
RV62_LVTMA_LNK8EN = 1 << 8,
|
||||
RV62_LVTMA_LNK9EN = 1 << 9,
|
||||
RV62_LVTMA_LNKL = RV62_LVTMA_LNK0EN | RV62_LVTMA_LNK1EN
|
||||
| RV62_LVTMA_LNK2EN | RV62_LVTMA_LNK3EN,
|
||||
RV62_LVTMA_LNKU = RV62_LVTMA_LNK4EN | RV62_LVTMA_LNK5EN
|
||||
| RV62_LVTMA_LNK6EN | RV62_LVTMA_LNK7EN,
|
||||
RV62_LVTMA_LNK_ALL = RV62_LVTMA_LNKL | RV62_LVTMA_LNKU
|
||||
| RV62_LVTMA_LNK8EN | RV62_LVTMA_LNK9EN,
|
||||
RV62_LVTMA_LNKEN_HPD_MASK = 1 << 16
|
||||
};
|
||||
|
||||
enum RV620_LVTMA_DATA_SYNCHRONIZATION {
|
||||
RV62_LVTMA_DSYNSEL = (1 << 0),
|
||||
RV62_LVTMA_PFREQCHG = (1 << 8)
|
||||
};
|
||||
|
||||
|
||||
enum RV620_DIG_CNTL_BITS {
|
||||
/* 0x75A0 */
|
||||
RV62_DIG_SWAP = (0x1 << 16),
|
||||
RV62_DIG_DUAL_LINK_ENABLE = (0x1 << 12),
|
||||
RV62_DIG_START = (0x1 << 6),
|
||||
RV62_DIG_MODE = (0x7 << 8),
|
||||
RV62_DIG_STEREOSYNC_SELECT = (1 << 2),
|
||||
RV62_DIG_SOURCE_SELECT = (1 << 0)
|
||||
};
|
||||
|
||||
enum RV620_DIG_LVDS_DATA_CNTL_BITS {
|
||||
/* 0x75BC */
|
||||
RV62_LVDS_24BIT_ENABLE = (0x1 << 0),
|
||||
RV62_LVDS_24BIT_FORMAT = (0x1 << 4)
|
||||
};
|
||||
|
||||
enum RV620_TMDS_CNTL_BITS {
|
||||
/* 0x75C0 */
|
||||
RV62_TMDS_PIXEL_ENCODING = (0x1 << 4),
|
||||
RV62_TMDS_COLOR_FORMAT = (0x3 << 8)
|
||||
};
|
||||
|
||||
enum RV620_FMT_BIT_DEPTH_CONTROL {
|
||||
RV62_FMT_TRUNCATE_EN = 1 << 0,
|
||||
RV62_FMT_TRUNCATE_DEPTH = 1 << 4,
|
||||
RV62_FMT_SPATIAL_DITHER_EN = 1 << 8,
|
||||
RV62_FMT_SPATIAL_DITHER_MODE = 1 << 9,
|
||||
RV62_FMT_SPATIAL_DITHER_DEPTH = 1 << 12,
|
||||
RV62_FMT_FRAME_RANDOM_ENABLE = 1 << 13,
|
||||
RV62_FMT_RGB_RANDOM_ENABLE = 1 << 14,
|
||||
RV62_FMT_HIGHPASS_RANDOM_ENABLE = 1 << 15,
|
||||
RV62_FMT_TEMPORAL_DITHER_EN = 1 << 16,
|
||||
RV62_FMT_TEMPORAL_DITHER_DEPTH = 1 << 20,
|
||||
RV62_FMT_TEMPORAL_DITHER_OFFSET = 3 << 21,
|
||||
RV62_FMT_TEMPORAL_LEVEL = 1 << 24,
|
||||
RV62_FMT_TEMPORAL_DITHER_RESET = 1 << 25,
|
||||
RV62_FMT_25FRC_SEL = 3 << 26,
|
||||
RV62_FMT_50FRC_SEL = 3 << 28,
|
||||
RV62_FMT_75FRC_SEL = 3 << 30
|
||||
};
|
||||
|
||||
enum RV620_FMT_CONTROL {
|
||||
RV62_FMT_PIXEL_ENCODING = 1 << 16
|
||||
};
|
||||
|
||||
enum _r5xxMCRegs {
|
||||
R5XX_MC_STATUS = 0x0000,
|
||||
RV515_MC_FB_LOCATION = 0x0001,
|
||||
R5XX_MC_FB_LOCATION = 0x0004,
|
||||
RV515_MC_STATUS = 0x0008
|
||||
};
|
||||
|
||||
enum _r5xxRegs {
|
||||
/* I2C */
|
||||
R5_DC_I2C_STATUS1 = 0x7D30, /* (RW) */
|
||||
R5_DC_I2C_RESET = 0x7D34, /* (RW) */
|
||||
R5_DC_I2C_CONTROL1 = 0x7D38, /* (RW) */
|
||||
R5_DC_I2C_CONTROL2 = 0x7D3C, /* (RW) */
|
||||
R5_DC_I2C_CONTROL3 = 0x7D40, /* (RW) */
|
||||
R5_DC_I2C_DATA = 0x7D44, /* (RW) */
|
||||
R5_DC_I2C_INTERRUPT_CONTROL = 0x7D48, /* (RW) */
|
||||
R5_DC_I2C_ARBITRATION = 0x7D50, /* (RW) */
|
||||
|
||||
R5_DC_GPIO_DDC1_MASK = 0x7E40, /* (RW) */
|
||||
R5_DC_GPIO_DDC1_A = 0x7E44, /* (RW) */
|
||||
R5_DC_GPIO_DDC1_EN = 0x7E48, /* (RW) */
|
||||
R5_DC_GPIO_DDC2_MASK = 0x7E50, /* (RW) */
|
||||
R5_DC_GPIO_DDC2_A = 0x7E54, /* (RW) */
|
||||
R5_DC_GPIO_DDC2_EN = 0x7E58, /* (RW) */
|
||||
R5_DC_GPIO_DDC3_MASK = 0x7E60, /* (RW) */
|
||||
R5_DC_GPIO_DDC3_A = 0x7E64, /* (RW) */
|
||||
R5_DC_GPIO_DDC3_EN = 0x7E68 /* (RW) */
|
||||
};
|
||||
|
||||
enum _r5xxSPLLRegs {
|
||||
SPLL_FUNC_CNTL = 0x0 /* (RW) */
|
||||
};
|
||||
|
||||
enum _r6xxRegs {
|
||||
/* MCLK */
|
||||
R6_MCLK_PWRMGT_CNTL = 0x620,
|
||||
/* I2C */
|
||||
R6_DC_I2C_CONTROL = 0x7D30, /* (RW) */
|
||||
R6_DC_I2C_ARBITRATION = 0x7D34, /* (RW) */
|
||||
R6_DC_I2C_INTERRUPT_CONTROL = 0x7D38, /* (RW) */
|
||||
R6_DC_I2C_SW_STATUS = 0x7d3c, /* (RW) */
|
||||
R6_DC_I2C_DDC1_SPEED = 0x7D4C, /* (RW) */
|
||||
R6_DC_I2C_DDC1_SETUP = 0x7D50, /* (RW) */
|
||||
R6_DC_I2C_DDC2_SPEED = 0x7D54, /* (RW) */
|
||||
R6_DC_I2C_DDC2_SETUP = 0x7D58, /* (RW) */
|
||||
R6_DC_I2C_DDC3_SPEED = 0x7D5C, /* (RW) */
|
||||
R6_DC_I2C_DDC3_SETUP = 0x7D60, /* (RW) */
|
||||
R6_DC_I2C_TRANSACTION0 = 0x7D64, /* (RW) */
|
||||
R6_DC_I2C_TRANSACTION1 = 0x7D68, /* (RW) */
|
||||
R6_DC_I2C_DATA = 0x7D74, /* (RW) */
|
||||
R6_DC_I2C_DDC4_SPEED = 0x7DB4, /* (RW) */
|
||||
R6_DC_I2C_DDC4_SETUP = 0x7DBC, /* (RW) */
|
||||
R6_DC_GPIO_DDC4_MASK = 0x7E00, /* (RW) */
|
||||
R6_DC_GPIO_DDC4_A = 0x7E04, /* (RW) */
|
||||
R6_DC_GPIO_DDC4_EN = 0x7E08, /* (RW) */
|
||||
R6_DC_GPIO_DDC1_MASK = 0x7E40, /* (RW) */
|
||||
R6_DC_GPIO_DDC1_A = 0x7E44, /* (RW) */
|
||||
R6_DC_GPIO_DDC1_EN = 0x7E48, /* (RW) */
|
||||
R6_DC_GPIO_DDC1_Y = 0x7E4C, /* (RW) */
|
||||
R6_DC_GPIO_DDC2_MASK = 0x7E50, /* (RW) */
|
||||
R6_DC_GPIO_DDC2_A = 0x7E54, /* (RW) */
|
||||
R6_DC_GPIO_DDC2_EN = 0x7E58, /* (RW) */
|
||||
R6_DC_GPIO_DDC2_Y = 0x7E5C, /* (RW) */
|
||||
R6_DC_GPIO_DDC3_MASK = 0x7E60, /* (RW) */
|
||||
R6_DC_GPIO_DDC3_A = 0x7E64, /* (RW) */
|
||||
R6_DC_GPIO_DDC3_EN = 0x7E68, /* (RW) */
|
||||
R6_DC_GPIO_DDC3_Y = 0x7E6C /* (RW) */
|
||||
};
|
||||
|
||||
enum R6_MCLK_PWRMGT_CNTL {
|
||||
R6_MC_BUSY = (1 << 5)
|
||||
};
|
||||
|
||||
|
||||
/* *_Q: questionbable */
|
||||
enum _rs69xRegs {
|
||||
/* I2C */
|
||||
RS69_DC_I2C_CONTROL = 0x7D30, /* (RW) *//* */
|
||||
RS69_DC_I2C_UNKNOWN_2 = 0x7D34, /* (RW) */
|
||||
RS69_DC_I2C_INTERRUPT_CONTROL = 0x7D38, /* (RW) */
|
||||
RS69_DC_I2C_SW_STATUS = 0x7d3c, /* (RW) *//**/
|
||||
RS69_DC_I2C_UNKNOWN_1 = 0x7d40,
|
||||
RS69_DC_I2C_DDC_SETUP_Q = 0x7D44, /* (RW) */
|
||||
RS69_DC_I2C_DATA = 0x7D58, /* (RW) *//**/
|
||||
RS69_DC_I2C_TRANSACTION0 = 0x7D48, /* (RW) *//**/
|
||||
RS69_DC_I2C_TRANSACTION1 = 0x7D4C, /* (RW) *//**/
|
||||
/* DDIA */
|
||||
RS69_DDIA_CNTL = 0x7200,
|
||||
RS69_DDIA_SOURCE_SELECT = 0x7204,
|
||||
RS69_DDIA_BIT_DEPTH_CONTROL = 0x7214,
|
||||
RS69_DDIA_DCBALANCER_CONTROL = 0x7250,
|
||||
RS69_DDIA_PATH_CONTROL = 0x7264,
|
||||
RS69_DDIA_PCIE_LINK_CONTROL2 = 0x7278,
|
||||
RS69_DDIA_PCIE_LINK_CONTROL3 = 0x727c,
|
||||
RS69_DDIA_PCIE_PHY_CONTROL1 = 0x728c,
|
||||
RS69_DDIA_PCIE_PHY_CONTROL2 = 0x7290
|
||||
};
|
||||
|
||||
enum RS69_DDIA_CNTL_BITS {
|
||||
RS69_DDIA_ENABLE = 1 << 0,
|
||||
RS69_DDIA_HDMI_EN = 1 << 2,
|
||||
RS69_DDIA_ENABLE_HPD_MASK = 1 << 4,
|
||||
RS69_DDIA_HPD_SELECT = 1 << 8,
|
||||
RS69_DDIA_SYNC_PHASE = 1 << 12,
|
||||
RS69_DDIA_PIXEL_ENCODING = 1 << 16,
|
||||
RS69_DDIA_DUAL_LINK_ENABLE = 1 << 24,
|
||||
RS69_DDIA_SWAP = 1 << 28
|
||||
};
|
||||
|
||||
enum RS69_DDIA_SOURCE_SELECT_BITS {
|
||||
RS69_DDIA_SOURCE_SELECT_BIT = 1 << 0,
|
||||
RS69_DDIA_SYNC_SELECT = 1 << 8,
|
||||
RS69_DDIA_STEREOSYNC_SELECT = 1 << 16
|
||||
};
|
||||
|
||||
enum RS69_DDIA_LINK_CONTROL2_SHIFT {
|
||||
RS69_DDIA_PCIE_OUTPUT_MUX_SEL0 = 0,
|
||||
RS69_DDIA_PCIE_OUTPUT_MUX_SEL1 = 4,
|
||||
RS69_DDIA_PCIE_OUTPUT_MUX_SEL2 = 8,
|
||||
RS69_DDIA_PCIE_OUTPUT_MUX_SEL3 = 12
|
||||
};
|
||||
|
||||
enum RS69_DDIA_BIT_DEPTH_CONTROL_BITS {
|
||||
RS69_DDIA_TRUNCATE_EN = 1 << 0,
|
||||
RS69_DDIA_TRUNCATE_DEPTH = 1 << 4,
|
||||
RS69_DDIA_SPATIAL_DITHER_EN = 1 << 8,
|
||||
RS69_DDIA_SPATIAL_DITHER_DEPTH = 1 << 12,
|
||||
RS69_DDIA_TEMPORAL_DITHER_EN = 1 << 16,
|
||||
RS69_DDIA_TEMPORAL_DITHER_DEPTH = 1 << 20,
|
||||
RS69_DDIA_TEMPORAL_LEVEL = 1 << 24,
|
||||
RS69_DDIA_TEMPORAL_DITHER_RESET = 1 << 25
|
||||
};
|
||||
|
||||
enum RS69_DDIA_DCBALANCER_CONTROL_BITS {
|
||||
RS69_DDIA_DCBALANCER_EN = 1 << 0,
|
||||
RS69_DDIA_SYNC_DCBAL_EN = 1 << 4,
|
||||
RS69_DDIA_DCBALANCER_TEST_EN = 1 << 8,
|
||||
RS69_DDIA_DCBALANCER_TEST_IN_SHIFT = 16,
|
||||
RS69_DDIA_DCBALANCER_FORCE = 1 << 24
|
||||
};
|
||||
|
||||
enum RS69_DDIA_PATH_CONTROL_BITS {
|
||||
RS69_DDIA_PATH_SELECT_SHIFT = 0,
|
||||
RS69_DDIA_DDPII_DE_ALIGN_EN = 1 << 4,
|
||||
RS69_DDIA_DDPII_TRAIN_EN = 1 << 8,
|
||||
RS69_DDIA_DDPII_TRAIN_SELECT = 1 << 12,
|
||||
RS69_DDIA_DDPII_SCRAMBLE_EN = 1 << 16,
|
||||
RS69_DDIA_REPL_MODE_SELECT = 1 << 20,
|
||||
RS69_DDIA_RB_30b_SWAP_EN = 1 << 24,
|
||||
RS69_DDIA_PIXVLD_RESET = 1 << 28,
|
||||
RS69_DDIA_REARRANGER_EN = 1 << 30
|
||||
};
|
||||
|
||||
enum RS69_DDIA_PCIE_LINK_CONTROL3_BITS {
|
||||
RS69_DDIA_PCIE_MIRROR_EN = 1 << 0,
|
||||
RS69_DDIA_PCIE_CFGDUALLINK = 1 << 4,
|
||||
RS69_DDIA_PCIE_NCHG3EN = 1 << 8,
|
||||
RS69_DDIA_PCIE_RX_PDNB_SHIFT = 12
|
||||
};
|
||||
|
||||
enum RS69_MC_INDEX_BITS {
|
||||
RS69_MC_IND_ADDR = (0x1 << 0),
|
||||
RS69_C_IND_WR_EN = (0x1 << 9)
|
||||
};
|
||||
|
||||
enum _rs690MCRegs {
|
||||
RS69_MC_SYSTEM_STATUS = 0x90, /* (RW) */
|
||||
RS69_MCCFG_FB_LOCATION = 0x100,
|
||||
RS69MCCFG_AGP_LOCATION = 0x101
|
||||
};
|
||||
|
||||
enum RS69_MC_SYSTEM_STATUS_BITS {
|
||||
RS69_MC_SYSTEM_IDLE = (0x1 << 0),
|
||||
RS69_MC_SEQUENCER_IDLE = (0x1 << 1),
|
||||
RS69_MC_ARBITER_IDLE = (0x1 << 2),
|
||||
RS69_MC_SELECT_PM = (0x1 << 3),
|
||||
RS69_RESERVED4 = (0xf << 4),
|
||||
RS69_RESERVED8 = (0xf << 8),
|
||||
RS69_RESERVED12_SYSTEM_STATUS = (0xf << 12),
|
||||
RS69_MCA_INIT_EXECUTED = (0x1 << 16),
|
||||
RS69_MCA_IDLE = (0x1 << 17),
|
||||
RS69_MCA_SEQ_IDLE = (0x1 << 18),
|
||||
RS69_MCA_ARB_IDLE = (0x1 << 19),
|
||||
RS69_RESERVED20_SYSTEM_STATUS = (0xfff << 20)
|
||||
};
|
||||
|
||||
enum R5XX_MC_STATUS_BITS {
|
||||
R5XX_MEM_PWRUP_COMPL = (0x1 << 0),
|
||||
R5XX_MC_IDLE = (0x1 << 1)
|
||||
};
|
||||
|
||||
enum RV515_MC_STATUS_BITS {
|
||||
RV515_MC_IDLE = (0x1 << 4)
|
||||
};
|
||||
|
||||
enum BUS_CNTL_BITS {
|
||||
/* BUS_CNTL */
|
||||
BUS_DBL_RESYNC = (0x1 << 0),
|
||||
BIOS_ROM_WRT_EN = (0x1 << 1),
|
||||
BIOS_ROM_DIS = (0x1 << 2),
|
||||
PMI_IO_DIS = (0x1 << 3),
|
||||
PMI_MEM_DIS = (0x1 << 4),
|
||||
PMI_BM_DIS = (0x1 << 5),
|
||||
PMI_INT_DIS = (0x1 << 6)
|
||||
};
|
||||
|
||||
enum SEPROM_SNTL1_BITS {
|
||||
/* SEPROM_CNTL1 */
|
||||
WRITE_ENABLE = (0x1 << 0),
|
||||
WRITE_DISABLE = (0x1 << 1),
|
||||
READ_CONFIG = (0x1 << 2),
|
||||
WRITE_CONFIG = (0x1 << 3),
|
||||
READ_STATUS = (0x1 << 4),
|
||||
SECT_TO_SRAM = (0x1 << 5),
|
||||
READY_BUSY = (0x1 << 7),
|
||||
SEPROM_BUSY = (0x1 << 8),
|
||||
BCNT_OVER_WTE_EN = (0x1 << 9),
|
||||
RB_MASKB = (0x1 << 10),
|
||||
SOFT_RESET = (0x1 << 11),
|
||||
STATE_IDLEb = (0x1 << 12),
|
||||
SECTOR_ERASE = (0x1 << 13),
|
||||
BYTE_CNT = (0xff << 16),
|
||||
SCK_PRESCALE = (0xff << 24)
|
||||
};
|
||||
|
||||
enum VIPH_CONTROL_BITS {
|
||||
/* VIPH_CONTROL */
|
||||
VIPH_CLK_SEL = (0xff << 0),
|
||||
VIPH_REG_RDY = (0x1 << 13),
|
||||
VIPH_MAX_WAIT = (0xf << 16),
|
||||
VIPH_DMA_MODE = (0x1 << 20),
|
||||
VIPH_EN = (0x1 << 21),
|
||||
VIPH_DV0_WID = (0x1 << 24),
|
||||
VIPH_DV1_WID = (0x1 << 25),
|
||||
VIPH_DV2_WID = (0x1 << 26),
|
||||
VIPH_DV3_WID = (0x1 << 27),
|
||||
VIPH_PWR_DOWN = (0x1 << 28),
|
||||
VIPH_PWR_DOWN_AK = (0x1 << 28),
|
||||
VIPH_VIPCLK_DIS = (0x1 << 29)
|
||||
};
|
||||
|
||||
enum VGA_RENDER_CONTROL_BITS {
|
||||
/* VGA_RENDER_CONTROL */
|
||||
VGA_BLINK_RATE = (0x1f << 0),
|
||||
VGA_BLINK_MODE = (0x3 << 5),
|
||||
VGA_CURSOR_BLINK_INVERT = (0x1 << 7),
|
||||
VGA_EXTD_ADDR_COUNT_ENABLE = (0x1 << 8),
|
||||
VGA_VSTATUS_CNTL = (0x3 << 16),
|
||||
VGA_LOCK_8DOT = (0x1 << 24),
|
||||
VGAREG_LINECMP_COMPATIBILITY_SEL = (0x1 << 25)
|
||||
};
|
||||
|
||||
enum D1VGA_CONTROL_BITS {
|
||||
/* D1VGA_CONTROL */
|
||||
D1VGA_MODE_ENABLE = (0x1 << 0),
|
||||
D1VGA_TIMING_SELECT = (0x1 << 8),
|
||||
D1VGA_SYNC_POLARITY_SELECT = (0x1 << 9),
|
||||
D1VGA_OVERSCAN_TIMING_SELECT = (0x1 << 10),
|
||||
D1VGA_OVERSCAN_COLOR_EN = (0x1 << 16),
|
||||
D1VGA_ROTATE = (0x3 << 24)
|
||||
};
|
||||
|
||||
enum D2VGA_CONTROL_BITS {
|
||||
/* D2VGA_CONTROL */
|
||||
D2VGA_MODE_ENABLE = (0x1 << 0),
|
||||
D2VGA_TIMING_SELECT = (0x1 << 8),
|
||||
D2VGA_SYNC_POLARITY_SELECT = (0x1 << 9),
|
||||
D2VGA_OVERSCAN_TIMING_SELECT = (0x1 << 10),
|
||||
D2VGA_OVERSCAN_COLOR_EN = (0x1 << 16),
|
||||
D2VGA_ROTATE = (0x3 << 24)
|
||||
};
|
||||
|
||||
enum {
|
||||
/* CLOCK_CNTL_INDEX */
|
||||
PLL_ADDR = (0x3f << 0),
|
||||
PLL_WR_EN = (0x1 << 7),
|
||||
PPLL_DIV_SEL = (0x3 << 8),
|
||||
|
||||
/* CLOCK_CNTL_DATA */
|
||||
#define PLL_DATA 0xffffffff
|
||||
|
||||
/* SPLL_FUNC_CNTL */
|
||||
SPLL_CHG_STATUS = (0x1 << 29),
|
||||
SPLL_BYPASS_EN = (0x1 << 25),
|
||||
|
||||
/* MC_IND_INDEX */
|
||||
MC_IND_ADDR = (0xffff << 0),
|
||||
MC_IND_SEQ_RBS_0 = (0x1 << 16),
|
||||
MC_IND_SEQ_RBS_1 = (0x1 << 17),
|
||||
MC_IND_SEQ_RBS_2 = (0x1 << 18),
|
||||
MC_IND_SEQ_RBS_3 = (0x1 << 19),
|
||||
MC_IND_AIC_RBS = (0x1 << 20),
|
||||
MC_IND_CITF_ARB0 = (0x1 << 21),
|
||||
MC_IND_CITF_ARB1 = (0x1 << 22),
|
||||
MC_IND_WR_EN = (0x1 << 23),
|
||||
MC_IND_RD_INV = (0x1 << 24)
|
||||
#define MC_IND_ALL (MC_IND_SEQ_RBS_0 | MC_IND_SEQ_RBS_1 \
|
||||
| MC_IND_SEQ_RBS_2 | MC_IND_SEQ_RBS_3 \
|
||||
| MC_IND_AIC_RBS | MC_IND_CITF_ARB0 | MC_IND_CITF_ARB1)
|
||||
|
||||
/* MC_IND_DATA */
|
||||
#define MC_IND_DATA_BIT 0xffffffff
|
||||
};
|
||||
|
||||
|
||||
#endif /* _RHD_REGS_H */
|
||||
566
drivers/video/ati2d/vs_prog.inc
Normal file
566
drivers/video/ati2d/vs_prog.inc
Normal file
@@ -0,0 +1,566 @@
|
||||
|
||||
typedef unsigned int u32_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VS_OUT_POS = 0,
|
||||
VS_OUT_PSIZE,
|
||||
VS_OUT_COL0,
|
||||
VS_OUT_COL1,
|
||||
VS_OUT_COL2,
|
||||
VS_OUT_COL3,
|
||||
VS_OUT_TEX0,
|
||||
VS_OUT_TEX1,
|
||||
VS_OUT_TEX2,
|
||||
VS_OUT_TEX3,
|
||||
VS_OUT_TEX4,
|
||||
VS_OUT_TEX5,
|
||||
VS_OUT_TEX6,
|
||||
VS_OUT_TEX7,
|
||||
VS_OUT_FOG,
|
||||
VS_OUT_MAX = 0xFFFFFFFF
|
||||
}v_out_t;
|
||||
|
||||
|
||||
#if 0
|
||||
vs_1_1
|
||||
|
||||
dcl_position v0
|
||||
dcl_color v1
|
||||
dcl_color1 v2
|
||||
dcl_fog v3
|
||||
dcl_psize v4
|
||||
dcl_texcoord v5
|
||||
dcl_texcoord1 v6
|
||||
|
||||
mov oPos, v0
|
||||
|
||||
mov oD0, v1
|
||||
mov oD1, v2
|
||||
|
||||
mov oFog, v3.x
|
||||
mov oPts, v4.x
|
||||
mov oT0, v5
|
||||
mov oT1, v6
|
||||
|
||||
#endif
|
||||
|
||||
const u32_t vs11[] =
|
||||
{
|
||||
0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
|
||||
0x900f0001, 0x0000001f, 0x8001000a, 0x900f0002, 0x0000001f, 0x8000000b,
|
||||
0x900f0003, 0x0000001f, 0x80000004, 0x900f0004, 0x0000001f, 0x80000005,
|
||||
0x900f0005, 0x0000001f, 0x80010005, 0x900f0006, 0x00000001, 0xc00f0000,
|
||||
0x90e40000, 0x00000001, 0xd00f0000, 0x90e40001, 0x00000001, 0xd00f0001,
|
||||
0x90e40002, 0x00000001, 0xc00f0001, 0x90000003, 0x00000001, 0xc00f0002,
|
||||
0x90000004, 0x00000001, 0xe00f0000, 0x90e40005, 0x00000001, 0xe00f0001,
|
||||
0x90e40006, 0x0000ffff
|
||||
};
|
||||
|
||||
char *sz_vs_command[] =
|
||||
{
|
||||
"nop",
|
||||
"mov",
|
||||
"add",
|
||||
"sub",
|
||||
"mad",
|
||||
"mul",
|
||||
"rcp",
|
||||
"rsq",
|
||||
"dp3",
|
||||
"dp4",
|
||||
"min",
|
||||
"max",
|
||||
"slt",
|
||||
"sge",
|
||||
"exp",
|
||||
"log",
|
||||
"lit",
|
||||
"dst",
|
||||
"lrp",
|
||||
"frc",
|
||||
"m4x4",
|
||||
"m4x3",
|
||||
"m3x4",
|
||||
"m3x3",
|
||||
"m3x2",
|
||||
};
|
||||
|
||||
/*
|
||||
char *sz_ps_command[] =
|
||||
{
|
||||
texcoord
|
||||
texkill
|
||||
tex
|
||||
texbem
|
||||
texbeml
|
||||
texreg2ar
|
||||
texreg2gb
|
||||
texm3x2pad
|
||||
texm3x3tex
|
||||
texm3x3pad
|
||||
texm3x3tex
|
||||
texm3x3diff
|
||||
texm3x3spec
|
||||
texm3x3vspec
|
||||
expp
|
||||
logp
|
||||
cnd
|
||||
def
|
||||
texreg2rgb
|
||||
texdp3tex
|
||||
texm3x2depth
|
||||
texdp3
|
||||
texm3x3
|
||||
texdepth
|
||||
cmp
|
||||
bem
|
||||
}
|
||||
*/
|
||||
|
||||
char *szusage[]=
|
||||
{
|
||||
"position",
|
||||
"blendweight",
|
||||
"blendindices",
|
||||
"normal",
|
||||
"psize",
|
||||
"texcoord",
|
||||
"tangent",
|
||||
"binormal",
|
||||
"tessfactor",
|
||||
"positiont",
|
||||
"color",
|
||||
"fog",
|
||||
"depth",
|
||||
"sample"
|
||||
};
|
||||
char *sztype[]=
|
||||
{
|
||||
"r",
|
||||
"v",
|
||||
"c"
|
||||
"a",
|
||||
"t",
|
||||
"rasout",
|
||||
"attrout",
|
||||
"texcrdout",
|
||||
"output",
|
||||
"constint",
|
||||
"colorout",
|
||||
"depthout",
|
||||
"sampler",
|
||||
"const2",
|
||||
"const3",
|
||||
"const4",
|
||||
"constbool",
|
||||
"loop",
|
||||
"tempfloat16",
|
||||
"misctype",
|
||||
"label",
|
||||
"predicate"
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t minor: 8;
|
||||
u32_t major: 8;
|
||||
u32_t type :16;
|
||||
}version_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t type:5;
|
||||
u32_t rsv :11;
|
||||
u32_t ind :4;
|
||||
u32_t rsv2:11;
|
||||
u32_t sign:1;
|
||||
}usage_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t ind :11;
|
||||
u32_t typeh :2;
|
||||
u32_t rsv :3;
|
||||
u32_t wr :4;
|
||||
u32_t mod :4;
|
||||
u32_t scale :4;
|
||||
u32_t typel :3;
|
||||
u32_t sign :1;
|
||||
}dst_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t ind :11;
|
||||
u32_t rsv :5;
|
||||
u32_t swzl :8;
|
||||
u32_t mod :4;
|
||||
u32_t typel :3;
|
||||
u32_t sign :1;
|
||||
}src_t;
|
||||
|
||||
|
||||
int parse_vs(const u32_t *stream);
|
||||
|
||||
static void assign_outputs();
|
||||
|
||||
int translate_vs(const u32_t *stream);
|
||||
|
||||
|
||||
u32_t vs_out_written;
|
||||
u32_t inp_mask;
|
||||
|
||||
u32_t vs_outputs[16];
|
||||
|
||||
int main()
|
||||
{
|
||||
version_t *ver;
|
||||
|
||||
ver = (version_t*)vs11;
|
||||
|
||||
if(ver->type == 0xFFFE)
|
||||
{
|
||||
printf("vs_%d_%d\n\n",ver->major,ver->minor);
|
||||
if( parse_vs(vs11+1) )
|
||||
translate_vs(vs11+1);
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static char txt_swzl[4] = {'x','y','z','w'};
|
||||
static char *txt_mod[2] = { "","_sat"};
|
||||
|
||||
int parse_vs(const u32_t *stream)
|
||||
{
|
||||
dst_t *dst;
|
||||
src_t *src;
|
||||
|
||||
u32_t swzl;
|
||||
u32_t wr;
|
||||
|
||||
char szswzl[5];
|
||||
char szwm[5];
|
||||
|
||||
int i,j;
|
||||
|
||||
while(1)
|
||||
{
|
||||
op_type_t instr = *stream++ & 0xFFFF;
|
||||
|
||||
switch( instr )
|
||||
{
|
||||
case D3DSIO_MOV:
|
||||
dst = (dst_t*)stream++;
|
||||
src = (src_t*)stream++;
|
||||
|
||||
swzl = src->swzl;
|
||||
wr = dst->wr;
|
||||
|
||||
for(i=0,j=0; i < 4; i++)
|
||||
{
|
||||
szswzl[i] = txt_swzl[swzl&3];
|
||||
swzl>>=2;
|
||||
if(wr & (1<<i))
|
||||
szwm[j++] = txt_swzl[i];
|
||||
};
|
||||
szswzl[4] = 0;
|
||||
szwm[j] = 0;
|
||||
|
||||
switch(dst->typel)
|
||||
{
|
||||
case 4: // Rasterizer Register File
|
||||
if(dst->ind == 0)
|
||||
vs_out_written |= (1 << VS_OUT_POS);
|
||||
else if (dst->ind == 1)
|
||||
vs_out_written |= (1 << VS_OUT_FOG);
|
||||
else if (dst->ind == 2)
|
||||
vs_out_written |= (1 << VS_OUT_PSIZE);
|
||||
else
|
||||
printf("invalid raster register %d",dst->ind);
|
||||
break;
|
||||
|
||||
case 5: // Attribute Output Register File
|
||||
if(dst->ind == 0)
|
||||
vs_out_written |= (1 << VS_OUT_COL0);
|
||||
else if (dst->ind == 1)
|
||||
vs_out_written |= (1 << VS_OUT_COL1);
|
||||
else
|
||||
printf("invalid attribute register %d",dst->ind);
|
||||
break;
|
||||
|
||||
case 6: // Texture Coordinate Output Register File
|
||||
if(dst->ind < 8)
|
||||
vs_out_written |= (1 << (VS_OUT_TEX0+dst->ind));
|
||||
else
|
||||
printf("invalid texture register %d",dst->ind);
|
||||
};
|
||||
printf("%s%s %s%d.%s,\t %s%d.%s\n",sz_vs_command[instr],txt_mod[dst->mod],
|
||||
sztype[dst->typel],dst->ind,szwm,
|
||||
sztype[src->typel],src->ind,szswzl);
|
||||
break;
|
||||
|
||||
case D3DSIO_DCL:
|
||||
parse_dcl(stream);
|
||||
stream+=2;
|
||||
break;
|
||||
case 0xFFFF:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
int parse_dcl(const u32_t *stream)
|
||||
{
|
||||
usage_t *usage;
|
||||
dst_t *dst;
|
||||
int dsttype;
|
||||
char szwm[5];
|
||||
int i;
|
||||
u32_t wr;
|
||||
|
||||
usage = (usage_t*)stream++;
|
||||
dst = (dst_t*)stream++;
|
||||
dsttype = (dst->typeh << 4) | dst->typel;
|
||||
wr = dst->wr;
|
||||
|
||||
for(i=0; wr; i++, wr>>=1)
|
||||
{
|
||||
if(wr & 1)
|
||||
szwm[i] = txt_swzl[i];
|
||||
};
|
||||
szwm[i] = 0;
|
||||
|
||||
printf("dcl_%s%d \t\t %s%d.%s\n",szusage[usage->type],usage->ind,
|
||||
sztype[dsttype],dst->ind, szwm);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int translate_dcl(const u32_t *stream);
|
||||
int translate_mov(const u32_t *stream);
|
||||
|
||||
int translate_vs(const u32_t *stream)
|
||||
{
|
||||
assign_outputs();
|
||||
|
||||
while(1)
|
||||
{
|
||||
op_type_t instr = *stream++ & 0xFFFF;
|
||||
|
||||
switch( instr )
|
||||
{
|
||||
case D3DSIO_MOV:
|
||||
translate_mov(stream);
|
||||
stream+=2;
|
||||
break;
|
||||
case D3DSIO_DCL:
|
||||
translate_dcl(stream);
|
||||
stream+=2;
|
||||
break;
|
||||
case 0xFFFF:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
int translate_dcl(const u32_t *stream)
|
||||
{
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
u32_t inst[4];
|
||||
|
||||
#include "r300_vertprog.h"
|
||||
|
||||
/**
|
||||
* Swizzle indexes.
|
||||
* Do not change!
|
||||
*/
|
||||
/*@{*/
|
||||
#define SWIZZLE_X 0
|
||||
#define SWIZZLE_Y 1
|
||||
#define SWIZZLE_Z 2
|
||||
#define SWIZZLE_W 3
|
||||
#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
|
||||
#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
|
||||
#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
|
||||
/*@}*/
|
||||
|
||||
#define __CONST(x, y) \
|
||||
(PVS_SRC_OPERAND(t_src_index(vp, &src[x]), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_src_class(src[x].File), \
|
||||
VSF_FLAG_NONE) | (src[x].RelAddr << 4))
|
||||
|
||||
static unsigned long t_swizzle(u32_t swizzle)
|
||||
{
|
||||
/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
static unsigned long t_dst_mask(u32_t mask)
|
||||
{
|
||||
/* WRITEMASK_* is equivalent to VSF_FLAG_* */
|
||||
return mask & VSF_FLAG_ALL;
|
||||
}
|
||||
|
||||
static unsigned long t_dst_class(int file)
|
||||
{
|
||||
|
||||
switch (file) {
|
||||
case 0: //D3DSPR_TEMP
|
||||
return PVS_DST_REG_TEMPORARY;
|
||||
case 3: //D3DSPR_ADDR
|
||||
return PVS_DST_REG_A0;
|
||||
case 4: //D3DSPR_RASTOUT
|
||||
case 5:
|
||||
case 6: //D3DSPR_TEXCRDOUT
|
||||
return PVS_DST_REG_OUT;
|
||||
|
||||
/*
|
||||
case PROGRAM_INPUT:
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
case PROGRAM_ENV_PARAM:
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_WRITE_ONLY:
|
||||
case PROGRAM_ADDRESS:
|
||||
*/
|
||||
default:
|
||||
printf("problem in %s", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long t_dst_index(dst_t *dst)
|
||||
{
|
||||
switch(dst->typel)
|
||||
{
|
||||
case 4:
|
||||
if(dst->ind == 0)
|
||||
return vs_outputs[VS_OUT_POS];
|
||||
else if (dst->ind == 1)
|
||||
return vs_outputs[VS_OUT_FOG];
|
||||
else if (dst->ind == 2)
|
||||
return vs_outputs[VS_OUT_PSIZE];
|
||||
break;
|
||||
case 5:
|
||||
if(dst->ind == 0)
|
||||
return vs_outputs[VS_OUT_COL0];
|
||||
else if (dst->ind == 1)
|
||||
return vs_outputs[VS_OUT_COL1];
|
||||
|
||||
case 6:
|
||||
return vs_outputs[VS_OUT_TEX0+dst->ind];
|
||||
|
||||
default:
|
||||
return dst->ind;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void assign_outputs()
|
||||
{
|
||||
int i;
|
||||
int cur_reg = 0;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
vs_outputs[i] = -1;
|
||||
|
||||
// assert(vs_out_written & (1 << VS_OUT_POS));
|
||||
|
||||
if (vs_out_written & (1 << VS_OUT_POS)) {
|
||||
vs_outputs[VS_OUT_POS] = cur_reg++;
|
||||
}
|
||||
|
||||
if (vs_out_written & (1 << VS_OUT_PSIZE)) {
|
||||
vs_outputs[VS_OUT_PSIZE] = cur_reg++;
|
||||
}
|
||||
|
||||
if (vs_out_written & (1 << VS_OUT_COL0)) {
|
||||
vs_outputs[VS_OUT_COL0] = cur_reg++;
|
||||
}
|
||||
|
||||
if (vs_out_written & (1 << VS_OUT_COL1)) {
|
||||
vs_outputs[VS_OUT_COL1] = vs_outputs[VS_OUT_COL0] + 1; // ???
|
||||
cur_reg = vs_outputs[VS_OUT_COL1] + 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) { //fog must be in
|
||||
vp->outputs[VERT_RESULT_FOGC] = cur_reg++; //one of the color regs
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = VS_OUT_TEX0; i <= VS_OUT_TEX7; i++) {
|
||||
if (vs_out_written & (1 << i)) {
|
||||
vs_outputs[i] = cur_reg++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int translate_mov(const u32_t *stream)
|
||||
{
|
||||
|
||||
dst_t *dst = (dst_t*)stream++;
|
||||
src_t *src = (src_t*)stream++;
|
||||
|
||||
int swzl = src->swzl;
|
||||
int wr = dst->wr;
|
||||
|
||||
|
||||
inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
|
||||
0,
|
||||
0,
|
||||
t_dst_index(dst),
|
||||
(dst->wr),
|
||||
t_dst_class(dst->typel));
|
||||
|
||||
//inst[1] = t_src(vp, &src[0]);
|
||||
// inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
//inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
printf("inst_0 %x\n", inst[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
static GLuint *r300TranslateOpcodeMOV(struct r300_vertex_program *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
{
|
||||
//ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
|
||||
|
||||
inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &src[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
|
||||
return inst;
|
||||
}
|
||||
*/
|
||||
2492
drivers/video/drm/drm_crtc.c
Normal file
2492
drivers/video/drm/drm_crtc.c
Normal file
File diff suppressed because it is too large
Load Diff
1149
drivers/video/drm/drm_crtc_helper.c
Normal file
1149
drivers/video/drm/drm_crtc_helper.c
Normal file
File diff suppressed because it is too large
Load Diff
801
drivers/video/drm/drm_edid.c
Normal file
801
drivers/video/drm/drm_edid.c
Normal file
@@ -0,0 +1,801 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Luc Verhaegen (quirks list)
|
||||
* Copyright (c) 2007-2008 Intel Corporation
|
||||
* Jesse Barnes <jesse.barnes@intel.com>
|
||||
*
|
||||
* DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
|
||||
* FB layer.
|
||||
* Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.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, sub license,
|
||||
* 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 (including the
|
||||
* next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*/
|
||||
//#include <linux/kernel.h>
|
||||
#include <types.h>
|
||||
#include <list.h>
|
||||
|
||||
#include <linux/idr.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
#include "drmP.h"
|
||||
#include "drm_edid.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - support EDID 1.4 (incl. CE blocks)
|
||||
*/
|
||||
|
||||
/*
|
||||
* EDID blocks out in the wild have a variety of bugs, try to collect
|
||||
* them here (note that userspace may work around broken monitors first,
|
||||
* but fixes should make their way here so that the kernel "just works"
|
||||
* on as many displays as possible).
|
||||
*/
|
||||
|
||||
/* First detailed mode wrong, use largest 60Hz mode */
|
||||
#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0)
|
||||
/* Reported 135MHz pixel clock is too high, needs adjustment */
|
||||
#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1)
|
||||
/* Prefer the largest mode at 75 Hz */
|
||||
#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2)
|
||||
/* Detail timing is in cm not mm */
|
||||
#define EDID_QUIRK_DETAILED_IN_CM (1 << 3)
|
||||
/* Detailed timing descriptors have bogus size values, so just take the
|
||||
* maximum size and use that.
|
||||
*/
|
||||
#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4)
|
||||
/* Monitor forgot to set the first detailed is preferred bit. */
|
||||
#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
|
||||
/* use +hsync +vsync for detailed mode */
|
||||
#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
|
||||
|
||||
static struct edid_quirk {
|
||||
char *vendor;
|
||||
int product_id;
|
||||
u32 quirks;
|
||||
} edid_quirk_list[] = {
|
||||
/* Acer AL1706 */
|
||||
{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
/* Acer F51 */
|
||||
{ "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
/* Unknown Acer */
|
||||
{ "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
|
||||
|
||||
/* Belinea 10 15 55 */
|
||||
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
|
||||
/* Envision Peripherals, Inc. EN-7100e */
|
||||
{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
|
||||
|
||||
/* Funai Electronics PM36B */
|
||||
{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
|
||||
EDID_QUIRK_DETAILED_IN_CM },
|
||||
|
||||
/* LG Philips LCD LP154W01-A5 */
|
||||
{ "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
||||
{ "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
|
||||
|
||||
/* Philips 107p5 CRT */
|
||||
{ "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
|
||||
|
||||
/* Proview AY765C */
|
||||
{ "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
|
||||
|
||||
/* Samsung SyncMaster 205BW. Note: irony */
|
||||
{ "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
|
||||
/* Samsung SyncMaster 22[5-6]BW */
|
||||
{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
|
||||
};
|
||||
|
||||
|
||||
/* Valid EDID header has these bytes */
|
||||
static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
||||
|
||||
/**
|
||||
* edid_is_valid - sanity check EDID data
|
||||
* @edid: EDID data
|
||||
*
|
||||
* Sanity check the EDID block by looking at the header, the version number
|
||||
* and the checksum. Return 0 if the EDID doesn't check out, or 1 if it's
|
||||
* valid.
|
||||
*/
|
||||
static bool edid_is_valid(struct edid *edid)
|
||||
{
|
||||
int i;
|
||||
u8 csum = 0;
|
||||
u8 *raw_edid = (u8 *)edid;
|
||||
|
||||
if (memcmp(edid->header, edid_header, sizeof(edid_header)))
|
||||
goto bad;
|
||||
if (edid->version != 1) {
|
||||
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
|
||||
goto bad;
|
||||
}
|
||||
if (edid->revision > 4)
|
||||
DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
|
||||
|
||||
for (i = 0; i < EDID_LENGTH; i++)
|
||||
csum += raw_edid[i];
|
||||
if (csum) {
|
||||
DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
if (raw_edid) {
|
||||
DRM_ERROR("Raw EDID:\n");
|
||||
// print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
|
||||
// printk("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* edid_vendor - match a string against EDID's obfuscated vendor field
|
||||
* @edid: EDID to match
|
||||
* @vendor: vendor string
|
||||
*
|
||||
* Returns true if @vendor is in @edid, false otherwise
|
||||
*/
|
||||
static bool edid_vendor(struct edid *edid, char *vendor)
|
||||
{
|
||||
char edid_vendor[3];
|
||||
|
||||
edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
|
||||
edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
|
||||
((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
|
||||
edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
|
||||
|
||||
return !strncmp(edid_vendor, vendor, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* edid_get_quirks - return quirk flags for a given EDID
|
||||
* @edid: EDID to process
|
||||
*
|
||||
* This tells subsequent routines what fixes they need to apply.
|
||||
*/
|
||||
static u32 edid_get_quirks(struct edid *edid)
|
||||
{
|
||||
struct edid_quirk *quirk;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
|
||||
quirk = &edid_quirk_list[i];
|
||||
|
||||
if (edid_vendor(edid, quirk->vendor) &&
|
||||
(EDID_PRODUCT_ID(edid) == quirk->product_id))
|
||||
return quirk->quirks;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
|
||||
#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
|
||||
|
||||
|
||||
/**
|
||||
* edid_fixup_preferred - set preferred modes based on quirk list
|
||||
* @connector: has mode list to fix up
|
||||
* @quirks: quirks list
|
||||
*
|
||||
* Walk the mode list for @connector, clearing the preferred status
|
||||
* on existing modes and setting it anew for the right mode ala @quirks.
|
||||
*/
|
||||
static void edid_fixup_preferred(struct drm_connector *connector,
|
||||
u32 quirks)
|
||||
{
|
||||
struct drm_display_mode *t, *cur_mode, *preferred_mode;
|
||||
int target_refresh = 0;
|
||||
|
||||
if (list_empty(&connector->probed_modes))
|
||||
return;
|
||||
|
||||
if (quirks & EDID_QUIRK_PREFER_LARGE_60)
|
||||
target_refresh = 60;
|
||||
if (quirks & EDID_QUIRK_PREFER_LARGE_75)
|
||||
target_refresh = 75;
|
||||
|
||||
preferred_mode = list_first_entry(&connector->probed_modes,
|
||||
struct drm_display_mode, head);
|
||||
|
||||
list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
|
||||
cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
|
||||
|
||||
if (cur_mode == preferred_mode)
|
||||
continue;
|
||||
|
||||
/* Largest mode is preferred */
|
||||
if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
|
||||
preferred_mode = cur_mode;
|
||||
|
||||
/* At a given size, try to get closest to target refresh */
|
||||
if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
|
||||
MODE_REFRESH_DIFF(cur_mode, target_refresh) <
|
||||
MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
|
||||
preferred_mode = cur_mode;
|
||||
}
|
||||
}
|
||||
|
||||
preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_std - convert standard mode info (width, height, refresh) into mode
|
||||
* @t: standard timing params
|
||||
*
|
||||
* Take the standard timing params (in this case width, aspect, and refresh)
|
||||
* and convert them into a real mode using CVT.
|
||||
*
|
||||
* Punts for now, but should eventually use the FB layer's CVT based mode
|
||||
* generation code.
|
||||
*/
|
||||
struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
||||
struct std_timing *t)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
int hsize = t->hsize * 8 + 248, vsize;
|
||||
unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
|
||||
>> EDID_TIMING_ASPECT_SHIFT;
|
||||
|
||||
mode = drm_mode_create(dev);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
if (aspect_ratio == 0)
|
||||
vsize = (hsize * 10) / 16;
|
||||
else if (aspect_ratio == 1)
|
||||
vsize = (hsize * 3) / 4;
|
||||
else if (aspect_ratio == 2)
|
||||
vsize = (hsize * 4) / 5;
|
||||
else
|
||||
vsize = (hsize * 9) / 16;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_detailed - create a new mode from an EDID detailed timing section
|
||||
* @dev: DRM device (needed to create new mode)
|
||||
* @edid: EDID block
|
||||
* @timing: EDID detailed timing info
|
||||
* @quirks: quirks to apply
|
||||
*
|
||||
* An EDID detailed timing block contains enough info for us to create and
|
||||
* return a new struct drm_display_mode.
|
||||
*/
|
||||
static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
||||
struct edid *edid,
|
||||
struct detailed_timing *timing,
|
||||
u32 quirks)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct detailed_pixel_timing *pt = &timing->data.pixel_data;
|
||||
unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
|
||||
unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
|
||||
unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
|
||||
unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
|
||||
unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
|
||||
unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
|
||||
unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
|
||||
unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
|
||||
|
||||
/* ignore tiny modes */
|
||||
if (hactive < 64 || vactive < 64)
|
||||
return NULL;
|
||||
|
||||
if (pt->misc & DRM_EDID_PT_STEREO) {
|
||||
printk(KERN_WARNING "stereo mode not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
|
||||
printk(KERN_WARNING "integrated sync not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = drm_mode_create(dev);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER;
|
||||
|
||||
if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
|
||||
timing->pixel_clock = cpu_to_le16(1088);
|
||||
|
||||
mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
|
||||
|
||||
mode->hdisplay = hactive;
|
||||
mode->hsync_start = mode->hdisplay + hsync_offset;
|
||||
mode->hsync_end = mode->hsync_start + hsync_pulse_width;
|
||||
mode->htotal = mode->hdisplay + hblank;
|
||||
|
||||
mode->vdisplay = vactive;
|
||||
mode->vsync_start = mode->vdisplay + vsync_offset;
|
||||
mode->vsync_end = mode->vsync_start + vsync_pulse_width;
|
||||
mode->vtotal = mode->vdisplay + vblank;
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
if (pt->misc & DRM_EDID_PT_INTERLACED)
|
||||
mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
|
||||
if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
|
||||
pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
|
||||
}
|
||||
|
||||
mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
|
||||
DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
|
||||
mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
|
||||
DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
|
||||
|
||||
mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
|
||||
mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
|
||||
|
||||
if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
|
||||
mode->width_mm *= 10;
|
||||
mode->height_mm *= 10;
|
||||
}
|
||||
|
||||
if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
|
||||
mode->width_mm = edid->width_cm * 10;
|
||||
mode->height_mm = edid->height_cm * 10;
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detailed mode info for the EDID "established modes" data to use.
|
||||
*/
|
||||
static struct drm_display_mode edid_est_modes[] = {
|
||||
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
|
||||
968, 1056, 0, 600, 601, 605, 628, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
|
||||
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
|
||||
896, 1024, 0, 600, 601, 603, 625, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
|
||||
720, 840, 0, 480, 481, 484, 500, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
|
||||
704, 832, 0, 480, 489, 491, 520, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
|
||||
768, 864, 0, 480, 483, 486, 525, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
|
||||
752, 800, 0, 480, 490, 492, 525, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
|
||||
{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
|
||||
846, 900, 0, 400, 421, 423, 449, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
|
||||
{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
|
||||
846, 900, 0, 400, 412, 414, 449, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
|
||||
{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
|
||||
1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
|
||||
1136, 1312, 0, 768, 769, 772, 800, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
|
||||
1184, 1328, 0, 768, 771, 777, 806, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
|
||||
1184, 1344, 0, 768, 771, 777, 806, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
|
||||
1208, 1264, 0, 768, 768, 776, 817, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
|
||||
{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
|
||||
928, 1152, 0, 624, 625, 628, 667, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
|
||||
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
|
||||
896, 1056, 0, 600, 601, 604, 625, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
|
||||
{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
|
||||
976, 1040, 0, 600, 637, 643, 666, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
|
||||
{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
|
||||
1344, 1600, 0, 864, 865, 868, 900, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
|
||||
};
|
||||
|
||||
#define EDID_EST_TIMINGS 16
|
||||
#define EDID_STD_TIMINGS 8
|
||||
#define EDID_DETAILED_TIMINGS 4
|
||||
|
||||
/**
|
||||
* add_established_modes - get est. modes from EDID and add them
|
||||
* @edid: EDID block to scan
|
||||
*
|
||||
* Each EDID block contains a bitmap of the supported "established modes" list
|
||||
* (defined above). Tease them out and add them to the global modes list.
|
||||
*/
|
||||
static int add_established_modes(struct drm_connector *connector, struct edid *edid)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
unsigned long est_bits = edid->established_timings.t1 |
|
||||
(edid->established_timings.t2 << 8) |
|
||||
((edid->established_timings.mfg_rsvd & 0x80) << 9);
|
||||
int i, modes = 0;
|
||||
|
||||
for (i = 0; i <= EDID_EST_TIMINGS; i++)
|
||||
if (est_bits & (1<<i)) {
|
||||
struct drm_display_mode *newmode;
|
||||
newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_standard_modes - get std. modes from EDID and add them
|
||||
* @edid: EDID block to scan
|
||||
*
|
||||
* Standard modes can be calculated using the CVT standard. Grab them from
|
||||
* @edid, calculate them, and add them to the list.
|
||||
*/
|
||||
static int add_standard_modes(struct drm_connector *connector, struct edid *edid)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
int i, modes = 0;
|
||||
|
||||
for (i = 0; i < EDID_STD_TIMINGS; i++) {
|
||||
struct std_timing *t = &edid->standard_timings[i];
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
/* If std timings bytes are 1, 1 it's empty */
|
||||
if (t->hsize == 1 && t->vfreq_aspect == 1)
|
||||
continue;
|
||||
|
||||
newmode = drm_mode_std(dev, &edid->standard_timings[i]);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_detailed_modes - get detailed mode info from EDID data
|
||||
* @connector: attached connector
|
||||
* @edid: EDID block to scan
|
||||
* @quirks: quirks to apply
|
||||
*
|
||||
* Some of the detailed timing sections may contain mode information. Grab
|
||||
* it and add it to the list.
|
||||
*/
|
||||
static int add_detailed_info(struct drm_connector *connector,
|
||||
struct edid *edid, u32 quirks)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
int i, j, modes = 0;
|
||||
|
||||
for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
|
||||
struct detailed_timing *timing = &edid->detailed_timings[i];
|
||||
struct detailed_non_pixel *data = &timing->data.other_data;
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
/* EDID up to and including 1.2 may put monitor info here */
|
||||
if (edid->version == 1 && edid->revision < 3)
|
||||
continue;
|
||||
|
||||
/* Detailed mode timing */
|
||||
if (timing->pixel_clock) {
|
||||
newmode = drm_mode_detailed(dev, edid, timing, quirks);
|
||||
if (!newmode)
|
||||
continue;
|
||||
|
||||
/* First detailed mode is preferred */
|
||||
if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING))
|
||||
newmode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
|
||||
modes++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Other timing or info */
|
||||
switch (data->type) {
|
||||
case EDID_DETAIL_MONITOR_SERIAL:
|
||||
break;
|
||||
case EDID_DETAIL_MONITOR_STRING:
|
||||
break;
|
||||
case EDID_DETAIL_MONITOR_RANGE:
|
||||
/* Get monitor range data */
|
||||
break;
|
||||
case EDID_DETAIL_MONITOR_NAME:
|
||||
break;
|
||||
case EDID_DETAIL_MONITOR_CPDATA:
|
||||
break;
|
||||
case EDID_DETAIL_STD_MODES:
|
||||
/* Five modes per detailed section */
|
||||
for (j = 0; j < 5; i++) {
|
||||
struct std_timing *std;
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
std = &data->data.timings[j];
|
||||
newmode = drm_mode_std(dev, std);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
#define DDC_ADDR 0x50
|
||||
/**
|
||||
* Get EDID information via I2C.
|
||||
*
|
||||
* \param adapter : i2c device adaptor
|
||||
* \param buf : EDID data buffer to be filled
|
||||
* \param len : EDID data buffer length
|
||||
* \return 0 on success or -1 on failure.
|
||||
*
|
||||
* Try to fetch EDID information by calling i2c driver function.
|
||||
*/
|
||||
int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
unsigned char start = 0x0;
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = DDC_ADDR,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = &start,
|
||||
}, {
|
||||
.addr = DDC_ADDR,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
if (i2c_transfer(adapter, msgs, 2) == 2)
|
||||
return 0;
|
||||
|
||||
// dev_info(&adapter->dev, "unable to read EDID block.\n");
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_do_probe_ddc_edid);
|
||||
|
||||
static int drm_ddc_read_edid(struct drm_connector *connector,
|
||||
struct i2c_adapter *adapter,
|
||||
char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_do_probe_ddc_edid(adapter, buf, len);
|
||||
if (ret != 0) {
|
||||
// dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
|
||||
// drm_get_connector_name(connector));
|
||||
goto end;
|
||||
}
|
||||
if (!edid_is_valid((struct edid *)buf)) {
|
||||
// dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
|
||||
// drm_get_connector_name(connector));
|
||||
ret = -1;
|
||||
}
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MAX_EDID_EXT_NUM 4
|
||||
/**
|
||||
* drm_get_edid - get EDID data, if available
|
||||
* @connector: connector we're probing
|
||||
* @adapter: i2c adapter to use for DDC
|
||||
*
|
||||
* Poke the given connector's i2c channel to grab EDID data if possible.
|
||||
*
|
||||
* Return edid data or NULL if we couldn't find any.
|
||||
*/
|
||||
struct edid *drm_get_edid(struct drm_connector *connector,
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
int ret;
|
||||
struct edid *edid;
|
||||
|
||||
edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
|
||||
GFP_KERNEL);
|
||||
if (edid == NULL) {
|
||||
// dev_warn(&connector->dev->pdev->dev,
|
||||
// "Failed to allocate EDID\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Read first EDID block */
|
||||
ret = drm_ddc_read_edid(connector, adapter,
|
||||
(unsigned char *)edid, EDID_LENGTH);
|
||||
if (ret != 0)
|
||||
goto clean_up;
|
||||
|
||||
/* There are EDID extensions to be read */
|
||||
if (edid->extensions != 0) {
|
||||
int edid_ext_num = edid->extensions;
|
||||
|
||||
if (edid_ext_num > MAX_EDID_EXT_NUM) {
|
||||
// dev_warn(&connector->dev->pdev->dev,
|
||||
// "The number of extension(%d) is "
|
||||
// "over max (%d), actually read number (%d)\n",
|
||||
// edid_ext_num, MAX_EDID_EXT_NUM,
|
||||
// MAX_EDID_EXT_NUM);
|
||||
/* Reset EDID extension number to be read */
|
||||
edid_ext_num = MAX_EDID_EXT_NUM;
|
||||
}
|
||||
/* Read EDID including extensions too */
|
||||
ret = drm_ddc_read_edid(connector, adapter, (char *)edid,
|
||||
EDID_LENGTH * (edid_ext_num + 1));
|
||||
if (ret != 0)
|
||||
goto clean_up;
|
||||
|
||||
}
|
||||
|
||||
connector->display_info.raw_edid = (char *)edid;
|
||||
goto end;
|
||||
|
||||
clean_up:
|
||||
kfree(edid);
|
||||
edid = NULL;
|
||||
end:
|
||||
return edid;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_edid);
|
||||
|
||||
#define HDMI_IDENTIFIER 0x000C03
|
||||
#define VENDOR_BLOCK 0x03
|
||||
/**
|
||||
* drm_detect_hdmi_monitor - detect whether monitor is hdmi.
|
||||
* @edid: monitor EDID information
|
||||
*
|
||||
* Parse the CEA extension according to CEA-861-B.
|
||||
* Return true if HDMI, false if not or unknown.
|
||||
*/
|
||||
bool drm_detect_hdmi_monitor(struct edid *edid)
|
||||
{
|
||||
char *edid_ext = NULL;
|
||||
int i, hdmi_id, edid_ext_num;
|
||||
int start_offset, end_offset;
|
||||
bool is_hdmi = false;
|
||||
|
||||
/* No EDID or EDID extensions */
|
||||
if (edid == NULL || edid->extensions == 0)
|
||||
goto end;
|
||||
|
||||
/* Chose real EDID extension number */
|
||||
edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
|
||||
MAX_EDID_EXT_NUM : edid->extensions;
|
||||
|
||||
/* Find CEA extension */
|
||||
for (i = 0; i < edid_ext_num; i++) {
|
||||
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
|
||||
/* This block is CEA extension */
|
||||
if (edid_ext[0] == 0x02)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == edid_ext_num)
|
||||
goto end;
|
||||
|
||||
/* Data block offset in CEA extension block */
|
||||
start_offset = 4;
|
||||
end_offset = edid_ext[2];
|
||||
|
||||
/*
|
||||
* Because HDMI identifier is in Vendor Specific Block,
|
||||
* search it from all data blocks of CEA extension.
|
||||
*/
|
||||
for (i = start_offset; i < end_offset;
|
||||
/* Increased by data block len */
|
||||
i += ((edid_ext[i] & 0x1f) + 1)) {
|
||||
/* Find vendor specific block */
|
||||
if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
|
||||
hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
|
||||
edid_ext[i + 3] << 16;
|
||||
/* Find HDMI identifier */
|
||||
if (hdmi_id == HDMI_IDENTIFIER)
|
||||
is_hdmi = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return is_hdmi;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_detect_hdmi_monitor);
|
||||
|
||||
/**
|
||||
* drm_add_edid_modes - add modes from EDID data, if available
|
||||
* @connector: connector we're probing
|
||||
* @edid: edid data
|
||||
*
|
||||
* Add the specified modes to the connector's mode list.
|
||||
*
|
||||
* Return number of modes added or 0 if we couldn't find any.
|
||||
*/
|
||||
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
|
||||
{
|
||||
int num_modes = 0;
|
||||
u32 quirks;
|
||||
|
||||
if (edid == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (!edid_is_valid(edid)) {
|
||||
// dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
|
||||
// drm_get_connector_name(connector));
|
||||
return 0;
|
||||
}
|
||||
|
||||
quirks = edid_get_quirks(edid);
|
||||
|
||||
num_modes += add_established_modes(connector, edid);
|
||||
num_modes += add_standard_modes(connector, edid);
|
||||
num_modes += add_detailed_info(connector, edid, quirks);
|
||||
|
||||
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
|
||||
edid_fixup_preferred(connector, quirks);
|
||||
|
||||
connector->display_info.serration_vsync = (edid->input & DRM_EDID_INPUT_SERRATION_VSYNC) ? 1 : 0;
|
||||
connector->display_info.sync_on_green = (edid->input & DRM_EDID_INPUT_SYNC_ON_GREEN) ? 1 : 0;
|
||||
connector->display_info.composite_sync = (edid->input & DRM_EDID_INPUT_COMPOSITE_SYNC) ? 1 : 0;
|
||||
connector->display_info.separate_syncs = (edid->input & DRM_EDID_INPUT_SEPARATE_SYNCS) ? 1 : 0;
|
||||
connector->display_info.blank_to_black = (edid->input & DRM_EDID_INPUT_BLANK_TO_BLACK) ? 1 : 0;
|
||||
connector->display_info.video_level = (edid->input & DRM_EDID_INPUT_VIDEO_LEVEL) >> 5;
|
||||
connector->display_info.digital = (edid->input & DRM_EDID_INPUT_DIGITAL) ? 1 : 0;
|
||||
connector->display_info.width_mm = edid->width_cm * 10;
|
||||
connector->display_info.height_mm = edid->height_cm * 10;
|
||||
connector->display_info.gamma = edid->gamma;
|
||||
connector->display_info.gtf_supported = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) ? 1 : 0;
|
||||
connector->display_info.standard_color = (edid->features & DRM_EDID_FEATURE_STANDARD_COLOR) ? 1 : 0;
|
||||
connector->display_info.display_type = (edid->features & DRM_EDID_FEATURE_DISPLAY_TYPE) >> 3;
|
||||
connector->display_info.active_off_supported = (edid->features & DRM_EDID_FEATURE_PM_ACTIVE_OFF) ? 1 : 0;
|
||||
connector->display_info.suspend_supported = (edid->features & DRM_EDID_FEATURE_PM_SUSPEND) ? 1 : 0;
|
||||
connector->display_info.standby_supported = (edid->features & DRM_EDID_FEATURE_PM_STANDBY) ? 1 : 0;
|
||||
connector->display_info.gamma = edid->gamma;
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_add_edid_modes);
|
||||
369
drivers/video/drm/drm_mm.c
Normal file
369
drivers/video/drm/drm_mm.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 (including the
|
||||
* next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Generic simple memory manager implementation. Intended to be used as a base
|
||||
* class implementation for more advanced memory managers.
|
||||
*
|
||||
* Note that the algorithm used is quite simple and there might be substantial
|
||||
* performance gains if a smarter free list is implemented. Currently it is just an
|
||||
* unordered stack of free regions. This could easily be improved if an RB-tree
|
||||
* is used instead. At least if we expect heavy fragmentation.
|
||||
*
|
||||
* Aligned allocations can also see improvement.
|
||||
*
|
||||
* Authors:
|
||||
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm_mm.h"
|
||||
//#include <linux/slab.h>
|
||||
|
||||
#define MM_UNUSED_TARGET 4
|
||||
|
||||
unsigned long drm_mm_tail_space(struct drm_mm *mm)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
struct drm_mm_node *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
|
||||
if (!entry->free)
|
||||
return 0;
|
||||
|
||||
return entry->size;
|
||||
}
|
||||
|
||||
int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
struct drm_mm_node *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
|
||||
if (!entry->free)
|
||||
return -ENOMEM;
|
||||
|
||||
if (entry->size <= size)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->size -= size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
|
||||
{
|
||||
struct drm_mm_node *child;
|
||||
|
||||
child = malloc(sizeof(*child));
|
||||
|
||||
if (unlikely(child == NULL)) {
|
||||
spin_lock(&mm->unused_lock);
|
||||
if (list_empty(&mm->unused_nodes))
|
||||
child = NULL;
|
||||
else {
|
||||
child =
|
||||
list_entry(mm->unused_nodes.next,
|
||||
struct drm_mm_node, fl_entry);
|
||||
list_del(&child->fl_entry);
|
||||
--mm->num_unused;
|
||||
}
|
||||
spin_unlock(&mm->unused_lock);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
int drm_mm_pre_get(struct drm_mm *mm)
|
||||
{
|
||||
struct drm_mm_node *node;
|
||||
|
||||
spin_lock(&mm->unused_lock);
|
||||
while (mm->num_unused < MM_UNUSED_TARGET) {
|
||||
spin_unlock(&mm->unused_lock);
|
||||
node = kmalloc(sizeof(*node), GFP_KERNEL);
|
||||
spin_lock(&mm->unused_lock);
|
||||
|
||||
if (unlikely(node == NULL)) {
|
||||
int ret = (mm->num_unused < 2) ? -ENOMEM : 0;
|
||||
spin_unlock(&mm->unused_lock);
|
||||
return ret;
|
||||
}
|
||||
++mm->num_unused;
|
||||
list_add_tail(&node->fl_entry, &mm->unused_nodes);
|
||||
}
|
||||
spin_unlock(&mm->unused_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_pre_get);
|
||||
|
||||
static int drm_mm_create_tail_node(struct drm_mm *mm,
|
||||
unsigned long start,
|
||||
unsigned long size, int atomic)
|
||||
{
|
||||
struct drm_mm_node *child;
|
||||
|
||||
child = drm_mm_kmalloc(mm, atomic);
|
||||
if (unlikely(child == NULL))
|
||||
return -ENOMEM;
|
||||
|
||||
child->free = 1;
|
||||
child->size = size;
|
||||
child->start = start;
|
||||
child->mm = mm;
|
||||
|
||||
list_add_tail(&child->ml_entry, &mm->ml_entry);
|
||||
list_add_tail(&child->fl_entry, &mm->fl_entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
struct drm_mm_node *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
|
||||
if (!entry->free) {
|
||||
return drm_mm_create_tail_node(mm, entry->start + entry->size,
|
||||
size, atomic);
|
||||
}
|
||||
entry->size += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
|
||||
unsigned long size,
|
||||
int atomic)
|
||||
{
|
||||
struct drm_mm_node *child;
|
||||
|
||||
child = drm_mm_kmalloc(parent->mm, atomic);
|
||||
if (unlikely(child == NULL))
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
child->free = 0;
|
||||
child->size = size;
|
||||
child->start = parent->start;
|
||||
child->mm = parent->mm;
|
||||
|
||||
list_add_tail(&child->ml_entry, &parent->ml_entry);
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
parent->size -= size;
|
||||
parent->start += size;
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
int atomic)
|
||||
{
|
||||
|
||||
struct drm_mm_node *align_splitoff = NULL;
|
||||
unsigned tmp = 0;
|
||||
|
||||
if (alignment)
|
||||
tmp = node->start % alignment;
|
||||
|
||||
if (tmp) {
|
||||
align_splitoff =
|
||||
drm_mm_split_at_start(node, alignment - tmp, atomic);
|
||||
if (unlikely(align_splitoff == NULL))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (node->size == size) {
|
||||
list_del_init(&node->fl_entry);
|
||||
node->free = 0;
|
||||
} else {
|
||||
node = drm_mm_split_at_start(node, size, atomic);
|
||||
}
|
||||
|
||||
if (align_splitoff)
|
||||
drm_mm_put_block(align_splitoff);
|
||||
|
||||
return node;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_get_block_generic);
|
||||
|
||||
/*
|
||||
* Put a block. Merge with the previous and / or next block if they are free.
|
||||
* Otherwise add to the free stack.
|
||||
*/
|
||||
|
||||
void drm_mm_put_block(struct drm_mm_node *cur)
|
||||
{
|
||||
|
||||
struct drm_mm *mm = cur->mm;
|
||||
struct list_head *cur_head = &cur->ml_entry;
|
||||
struct list_head *root_head = &mm->ml_entry;
|
||||
struct drm_mm_node *prev_node = NULL;
|
||||
struct drm_mm_node *next_node;
|
||||
|
||||
int merged = 0;
|
||||
|
||||
if (cur_head->prev != root_head) {
|
||||
prev_node =
|
||||
list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
|
||||
if (prev_node->free) {
|
||||
prev_node->size += cur->size;
|
||||
merged = 1;
|
||||
}
|
||||
}
|
||||
if (cur_head->next != root_head) {
|
||||
next_node =
|
||||
list_entry(cur_head->next, struct drm_mm_node, ml_entry);
|
||||
if (next_node->free) {
|
||||
if (merged) {
|
||||
prev_node->size += next_node->size;
|
||||
list_del(&next_node->ml_entry);
|
||||
list_del(&next_node->fl_entry);
|
||||
if (mm->num_unused < MM_UNUSED_TARGET) {
|
||||
list_add(&next_node->fl_entry,
|
||||
&mm->unused_nodes);
|
||||
++mm->num_unused;
|
||||
} else
|
||||
kfree(next_node);
|
||||
} else {
|
||||
next_node->size += cur->size;
|
||||
next_node->start = cur->start;
|
||||
merged = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!merged) {
|
||||
cur->free = 1;
|
||||
list_add(&cur->fl_entry, &mm->fl_entry);
|
||||
} else {
|
||||
list_del(&cur->ml_entry);
|
||||
if (mm->num_unused < MM_UNUSED_TARGET) {
|
||||
list_add(&cur->fl_entry, &mm->unused_nodes);
|
||||
++mm->num_unused;
|
||||
} else
|
||||
kfree(cur);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_mm_put_block);
|
||||
|
||||
struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
|
||||
unsigned long size,
|
||||
unsigned alignment, int best_match)
|
||||
{
|
||||
struct list_head *list;
|
||||
const struct list_head *free_stack = &mm->fl_entry;
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_mm_node *best;
|
||||
unsigned long best_size;
|
||||
unsigned wasted;
|
||||
|
||||
best = NULL;
|
||||
best_size = ~0UL;
|
||||
|
||||
list_for_each(list, free_stack) {
|
||||
entry = list_entry(list, struct drm_mm_node, fl_entry);
|
||||
wasted = 0;
|
||||
|
||||
if (entry->size < size)
|
||||
continue;
|
||||
|
||||
if (alignment) {
|
||||
register unsigned tmp = entry->start % alignment;
|
||||
if (tmp)
|
||||
wasted += alignment - tmp;
|
||||
}
|
||||
|
||||
if (entry->size >= size + wasted) {
|
||||
if (!best_match)
|
||||
return entry;
|
||||
if (size < best_size) {
|
||||
best = entry;
|
||||
best_size = entry->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_search_free);
|
||||
|
||||
int drm_mm_clean(struct drm_mm * mm)
|
||||
{
|
||||
struct list_head *head = &mm->ml_entry;
|
||||
|
||||
return (head->next->next == head);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_clean);
|
||||
|
||||
int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
|
||||
{
|
||||
INIT_LIST_HEAD(&mm->ml_entry);
|
||||
INIT_LIST_HEAD(&mm->fl_entry);
|
||||
INIT_LIST_HEAD(&mm->unused_nodes);
|
||||
mm->num_unused = 0;
|
||||
spin_lock_init(&mm->unused_lock);
|
||||
|
||||
return drm_mm_create_tail_node(mm, start, size, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_init);
|
||||
|
||||
void drm_mm_takedown(struct drm_mm * mm)
|
||||
{
|
||||
struct list_head *bnode = mm->fl_entry.next;
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_mm_node *next;
|
||||
|
||||
entry = list_entry(bnode, struct drm_mm_node, fl_entry);
|
||||
|
||||
if (entry->ml_entry.next != &mm->ml_entry ||
|
||||
entry->fl_entry.next != &mm->fl_entry) {
|
||||
DRM_ERROR("Memory manager not clean. Delaying takedown\n");
|
||||
return;
|
||||
}
|
||||
|
||||
list_del(&entry->fl_entry);
|
||||
list_del(&entry->ml_entry);
|
||||
kfree(entry);
|
||||
|
||||
spin_lock(&mm->unused_lock);
|
||||
list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) {
|
||||
list_del(&entry->fl_entry);
|
||||
kfree(entry);
|
||||
--mm->num_unused;
|
||||
}
|
||||
spin_unlock(&mm->unused_lock);
|
||||
|
||||
BUG_ON(mm->num_unused != 0);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_takedown);
|
||||
580
drivers/video/drm/drm_modes.c
Normal file
580
drivers/video/drm/drm_modes.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
* The list_sort function is (presumably) licensed under the GPL (see the
|
||||
* top level "COPYING" file for details).
|
||||
*
|
||||
* The remainder of this file is:
|
||||
*
|
||||
* Copyright © 1997-2003 by The XFree86 Project, Inc.
|
||||
* Copyright © 2007 Dave Airlie
|
||||
* Copyright © 2007-2008 Intel Corporation
|
||||
* Jesse Barnes <jesse.barnes@intel.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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the copyright holder(s)
|
||||
* and author(s) shall not be used in advertising or otherwise to promote
|
||||
* the sale, use or other dealings in this Software without prior written
|
||||
* authorization from the copyright holder(s) and author(s).
|
||||
*/
|
||||
|
||||
#include <list.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "drm_crtc.h"
|
||||
|
||||
#define DRM_MODESET_DEBUG "drm_mode"
|
||||
/**
|
||||
* drm_mode_debug_printmodeline - debug print a mode
|
||||
* @dev: DRM device
|
||||
* @mode: mode to print
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Describe @mode using DRM_DEBUG.
|
||||
*/
|
||||
void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
|
||||
{
|
||||
DRM_DEBUG_MODE(DRM_MODESET_DEBUG,
|
||||
"Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
|
||||
mode->base.id, mode->name, mode->vrefresh, mode->clock,
|
||||
mode->hdisplay, mode->hsync_start,
|
||||
mode->hsync_end, mode->htotal,
|
||||
mode->vdisplay, mode->vsync_start,
|
||||
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_debug_printmodeline);
|
||||
|
||||
/**
|
||||
* drm_mode_set_name - set the name on a mode
|
||||
* @mode: name will be set in this mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Set the name of @mode to a standard format.
|
||||
*/
|
||||
void drm_mode_set_name(struct drm_display_mode *mode)
|
||||
{
|
||||
snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay,
|
||||
mode->vdisplay);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_set_name);
|
||||
|
||||
/**
|
||||
* drm_mode_list_concat - move modes from one list to another
|
||||
* @head: source list
|
||||
* @new: dst list
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must ensure both lists are locked.
|
||||
*
|
||||
* Move all the modes from @head to @new.
|
||||
*/
|
||||
void drm_mode_list_concat(struct list_head *head, struct list_head *new)
|
||||
{
|
||||
|
||||
struct list_head *entry, *tmp;
|
||||
|
||||
list_for_each_safe(entry, tmp, head) {
|
||||
list_move_tail(entry, new);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_list_concat);
|
||||
|
||||
/**
|
||||
* drm_mode_width - get the width of a mode
|
||||
* @mode: mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Return @mode's width (hdisplay) value.
|
||||
*
|
||||
* FIXME: is this needed?
|
||||
*
|
||||
* RETURNS:
|
||||
* @mode->hdisplay
|
||||
*/
|
||||
int drm_mode_width(struct drm_display_mode *mode)
|
||||
{
|
||||
return mode->hdisplay;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_width);
|
||||
|
||||
/**
|
||||
* drm_mode_height - get the height of a mode
|
||||
* @mode: mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Return @mode's height (vdisplay) value.
|
||||
*
|
||||
* FIXME: is this needed?
|
||||
*
|
||||
* RETURNS:
|
||||
* @mode->vdisplay
|
||||
*/
|
||||
int drm_mode_height(struct drm_display_mode *mode)
|
||||
{
|
||||
return mode->vdisplay;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_height);
|
||||
|
||||
/**
|
||||
* drm_mode_vrefresh - get the vrefresh of a mode
|
||||
* @mode: mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Return @mode's vrefresh rate or calculate it if necessary.
|
||||
*
|
||||
* FIXME: why is this needed? shouldn't vrefresh be set already?
|
||||
*
|
||||
* RETURNS:
|
||||
* Vertical refresh rate of @mode x 1000. For precision reasons.
|
||||
*/
|
||||
int drm_mode_vrefresh(struct drm_display_mode *mode)
|
||||
{
|
||||
int refresh = 0;
|
||||
unsigned int calc_val;
|
||||
|
||||
if (mode->vrefresh > 0)
|
||||
refresh = mode->vrefresh;
|
||||
else if (mode->htotal > 0 && mode->vtotal > 0) {
|
||||
/* work out vrefresh the value will be x1000 */
|
||||
calc_val = (mode->clock * 1000);
|
||||
|
||||
calc_val /= mode->htotal;
|
||||
calc_val *= 1000;
|
||||
calc_val /= mode->vtotal;
|
||||
|
||||
refresh = calc_val;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
refresh *= 2;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
refresh /= 2;
|
||||
if (mode->vscan > 1)
|
||||
refresh /= mode->vscan;
|
||||
}
|
||||
return refresh;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_vrefresh);
|
||||
|
||||
/**
|
||||
* drm_mode_set_crtcinfo - set CRTC modesetting parameters
|
||||
* @p: mode
|
||||
* @adjust_flags: unused? (FIXME)
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Setup the CRTC modesetting parameters for @p, adjusting if necessary.
|
||||
*/
|
||||
void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
|
||||
{
|
||||
if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN))
|
||||
return;
|
||||
|
||||
p->crtc_hdisplay = p->hdisplay;
|
||||
p->crtc_hsync_start = p->hsync_start;
|
||||
p->crtc_hsync_end = p->hsync_end;
|
||||
p->crtc_htotal = p->htotal;
|
||||
p->crtc_hskew = p->hskew;
|
||||
p->crtc_vdisplay = p->vdisplay;
|
||||
p->crtc_vsync_start = p->vsync_start;
|
||||
p->crtc_vsync_end = p->vsync_end;
|
||||
p->crtc_vtotal = p->vtotal;
|
||||
|
||||
if (p->flags & DRM_MODE_FLAG_INTERLACE) {
|
||||
if (adjust_flags & CRTC_INTERLACE_HALVE_V) {
|
||||
p->crtc_vdisplay /= 2;
|
||||
p->crtc_vsync_start /= 2;
|
||||
p->crtc_vsync_end /= 2;
|
||||
p->crtc_vtotal /= 2;
|
||||
}
|
||||
|
||||
p->crtc_vtotal |= 1;
|
||||
}
|
||||
|
||||
if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
|
||||
p->crtc_vdisplay *= 2;
|
||||
p->crtc_vsync_start *= 2;
|
||||
p->crtc_vsync_end *= 2;
|
||||
p->crtc_vtotal *= 2;
|
||||
}
|
||||
|
||||
if (p->vscan > 1) {
|
||||
p->crtc_vdisplay *= p->vscan;
|
||||
p->crtc_vsync_start *= p->vscan;
|
||||
p->crtc_vsync_end *= p->vscan;
|
||||
p->crtc_vtotal *= p->vscan;
|
||||
}
|
||||
|
||||
p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay);
|
||||
p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);
|
||||
p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);
|
||||
p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal);
|
||||
|
||||
p->crtc_hadjusted = false;
|
||||
p->crtc_vadjusted = false;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_set_crtcinfo);
|
||||
|
||||
|
||||
/**
|
||||
* drm_mode_duplicate - allocate and duplicate an existing mode
|
||||
* @m: mode to duplicate
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Just allocate a new mode, copy the existing mode into it, and return
|
||||
* a pointer to it. Used to create new instances of established modes.
|
||||
*/
|
||||
struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_display_mode *nmode;
|
||||
int new_id;
|
||||
|
||||
nmode = drm_mode_create(dev);
|
||||
if (!nmode)
|
||||
return NULL;
|
||||
|
||||
new_id = nmode->base.id;
|
||||
*nmode = *mode;
|
||||
nmode->base.id = new_id;
|
||||
INIT_LIST_HEAD(&nmode->head);
|
||||
return nmode;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_duplicate);
|
||||
|
||||
/**
|
||||
* drm_mode_equal - test modes for equality
|
||||
* @mode1: first mode
|
||||
* @mode2: second mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Check to see if @mode1 and @mode2 are equivalent.
|
||||
*
|
||||
* RETURNS:
|
||||
* True if the modes are equal, false otherwise.
|
||||
*/
|
||||
bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2)
|
||||
{
|
||||
/* do clock check convert to PICOS so fb modes get matched
|
||||
* the same */
|
||||
if (mode1->clock && mode2->clock) {
|
||||
if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock))
|
||||
return false;
|
||||
} else if (mode1->clock != mode2->clock)
|
||||
return false;
|
||||
|
||||
if (mode1->hdisplay == mode2->hdisplay &&
|
||||
mode1->hsync_start == mode2->hsync_start &&
|
||||
mode1->hsync_end == mode2->hsync_end &&
|
||||
mode1->htotal == mode2->htotal &&
|
||||
mode1->hskew == mode2->hskew &&
|
||||
mode1->vdisplay == mode2->vdisplay &&
|
||||
mode1->vsync_start == mode2->vsync_start &&
|
||||
mode1->vsync_end == mode2->vsync_end &&
|
||||
mode1->vtotal == mode2->vtotal &&
|
||||
mode1->vscan == mode2->vscan &&
|
||||
mode1->flags == mode2->flags)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_equal);
|
||||
|
||||
/**
|
||||
* drm_mode_validate_size - make sure modes adhere to size constraints
|
||||
* @dev: DRM device
|
||||
* @mode_list: list of modes to check
|
||||
* @maxX: maximum width
|
||||
* @maxY: maximum height
|
||||
* @maxPitch: max pitch
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must hold a lock protecting @mode_list.
|
||||
*
|
||||
* The DRM device (@dev) has size and pitch limits. Here we validate the
|
||||
* modes we probed for @dev against those limits and set their status as
|
||||
* necessary.
|
||||
*/
|
||||
void drm_mode_validate_size(struct drm_device *dev,
|
||||
struct list_head *mode_list,
|
||||
int maxX, int maxY, int maxPitch)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
list_for_each_entry(mode, mode_list, head) {
|
||||
if (maxPitch > 0 && mode->hdisplay > maxPitch)
|
||||
mode->status = MODE_BAD_WIDTH;
|
||||
|
||||
if (maxX > 0 && mode->hdisplay > maxX)
|
||||
mode->status = MODE_VIRTUAL_X;
|
||||
|
||||
if (maxY > 0 && mode->vdisplay > maxY)
|
||||
mode->status = MODE_VIRTUAL_Y;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_validate_size);
|
||||
|
||||
/**
|
||||
* drm_mode_validate_clocks - validate modes against clock limits
|
||||
* @dev: DRM device
|
||||
* @mode_list: list of modes to check
|
||||
* @min: minimum clock rate array
|
||||
* @max: maximum clock rate array
|
||||
* @n_ranges: number of clock ranges (size of arrays)
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must hold a lock protecting @mode_list.
|
||||
*
|
||||
* Some code may need to check a mode list against the clock limits of the
|
||||
* device in question. This function walks the mode list, testing to make
|
||||
* sure each mode falls within a given range (defined by @min and @max
|
||||
* arrays) and sets @mode->status as needed.
|
||||
*/
|
||||
void drm_mode_validate_clocks(struct drm_device *dev,
|
||||
struct list_head *mode_list,
|
||||
int *min, int *max, int n_ranges)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
int i;
|
||||
|
||||
list_for_each_entry(mode, mode_list, head) {
|
||||
bool good = false;
|
||||
for (i = 0; i < n_ranges; i++) {
|
||||
if (mode->clock >= min[i] && mode->clock <= max[i]) {
|
||||
good = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!good)
|
||||
mode->status = MODE_CLOCK_RANGE;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_validate_clocks);
|
||||
|
||||
/**
|
||||
* drm_mode_prune_invalid - remove invalid modes from mode list
|
||||
* @dev: DRM device
|
||||
* @mode_list: list of modes to check
|
||||
* @verbose: be verbose about it
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must hold a lock protecting @mode_list.
|
||||
*
|
||||
* Once mode list generation is complete, a caller can use this routine to
|
||||
* remove invalid modes from a mode list. If any of the modes have a
|
||||
* status other than %MODE_OK, they are removed from @mode_list and freed.
|
||||
*/
|
||||
void drm_mode_prune_invalid(struct drm_device *dev,
|
||||
struct list_head *mode_list, bool verbose)
|
||||
{
|
||||
struct drm_display_mode *mode, *t;
|
||||
|
||||
list_for_each_entry_safe(mode, t, mode_list, head) {
|
||||
if (mode->status != MODE_OK) {
|
||||
list_del(&mode->head);
|
||||
if (verbose) {
|
||||
drm_mode_debug_printmodeline(mode);
|
||||
DRM_DEBUG_MODE(DRM_MODESET_DEBUG,
|
||||
"Not using %s mode %d\n",
|
||||
mode->name, mode->status);
|
||||
}
|
||||
drm_mode_destroy(dev, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_prune_invalid);
|
||||
|
||||
/**
|
||||
* drm_mode_compare - compare modes for favorability
|
||||
* @lh_a: list_head for first mode
|
||||
* @lh_b: list_head for second mode
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Compare two modes, given by @lh_a and @lh_b, returning a value indicating
|
||||
* which is better.
|
||||
*
|
||||
* RETURNS:
|
||||
* Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
|
||||
* positive if @lh_b is better than @lh_a.
|
||||
*/
|
||||
static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b)
|
||||
{
|
||||
struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head);
|
||||
struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head);
|
||||
int diff;
|
||||
|
||||
diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) -
|
||||
((a->type & DRM_MODE_TYPE_PREFERRED) != 0);
|
||||
if (diff)
|
||||
return diff;
|
||||
diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay;
|
||||
if (diff)
|
||||
return diff;
|
||||
diff = b->clock - a->clock;
|
||||
return diff;
|
||||
}
|
||||
|
||||
/* FIXME: what we don't have a list sort function? */
|
||||
/* list sort from Mark J Roberts (mjr@znex.org) */
|
||||
void list_sort(struct list_head *head,
|
||||
int (*cmp)(struct list_head *a, struct list_head *b))
|
||||
{
|
||||
struct list_head *p, *q, *e, *list, *tail, *oldhead;
|
||||
int insize, nmerges, psize, qsize, i;
|
||||
|
||||
list = head->next;
|
||||
list_del(head);
|
||||
insize = 1;
|
||||
for (;;) {
|
||||
p = oldhead = list;
|
||||
list = tail = NULL;
|
||||
nmerges = 0;
|
||||
|
||||
while (p) {
|
||||
nmerges++;
|
||||
q = p;
|
||||
psize = 0;
|
||||
for (i = 0; i < insize; i++) {
|
||||
psize++;
|
||||
q = q->next == oldhead ? NULL : q->next;
|
||||
if (!q)
|
||||
break;
|
||||
}
|
||||
|
||||
qsize = insize;
|
||||
while (psize > 0 || (qsize > 0 && q)) {
|
||||
if (!psize) {
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
if (q == oldhead)
|
||||
q = NULL;
|
||||
} else if (!qsize || !q) {
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
if (p == oldhead)
|
||||
p = NULL;
|
||||
} else if (cmp(p, q) <= 0) {
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
if (p == oldhead)
|
||||
p = NULL;
|
||||
} else {
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
if (q == oldhead)
|
||||
q = NULL;
|
||||
}
|
||||
if (tail)
|
||||
tail->next = e;
|
||||
else
|
||||
list = e;
|
||||
e->prev = tail;
|
||||
tail = e;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
tail->next = list;
|
||||
list->prev = tail;
|
||||
|
||||
if (nmerges <= 1)
|
||||
break;
|
||||
|
||||
insize *= 2;
|
||||
}
|
||||
|
||||
head->next = list;
|
||||
head->prev = list->prev;
|
||||
list->prev->next = head;
|
||||
list->prev = head;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_sort - sort mode list
|
||||
* @mode_list: list to sort
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must hold a lock protecting @mode_list.
|
||||
*
|
||||
* Sort @mode_list by favorability, putting good modes first.
|
||||
*/
|
||||
void drm_mode_sort(struct list_head *mode_list)
|
||||
{
|
||||
list_sort(mode_list, drm_mode_compare);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_sort);
|
||||
|
||||
/**
|
||||
* drm_mode_connector_list_update - update the mode list for the connector
|
||||
* @connector: the connector to update
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller must hold a lock protecting @mode_list.
|
||||
*
|
||||
* This moves the modes from the @connector probed_modes list
|
||||
* to the actual mode list. It compares the probed mode against the current
|
||||
* list and only adds different modes. All modes unverified after this point
|
||||
* will be removed by the prune invalid modes.
|
||||
*/
|
||||
void drm_mode_connector_list_update(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct drm_display_mode *pmode, *pt;
|
||||
int found_it;
|
||||
|
||||
list_for_each_entry_safe(pmode, pt, &connector->probed_modes,
|
||||
head) {
|
||||
found_it = 0;
|
||||
/* go through current modes checking for the new probed mode */
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
if (drm_mode_equal(pmode, mode)) {
|
||||
found_it = 1;
|
||||
/* if equal delete the probed mode */
|
||||
mode->status = pmode->status;
|
||||
list_del(&pmode->head);
|
||||
drm_mode_destroy(connector->dev, pmode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_it) {
|
||||
list_move_tail(&pmode->head, &connector->modes);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_connector_list_update);
|
||||
615
drivers/video/drm/i2c/i2c-algo-bit.c
Normal file
615
drivers/video/drm/i2c/i2c-algo-bit.c
Normal file
@@ -0,0 +1,615 @@
|
||||
/* -------------------------------------------------------------------------
|
||||
* i2c-algo-bit.c i2c driver algorithms for bit-shift adapters
|
||||
* -------------------------------------------------------------------------
|
||||
* Copyright (C) 1995-2000 Simon G. Vogl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
|
||||
<kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
|
||||
|
||||
#include <types.h>
|
||||
#include <list.h>
|
||||
#include <syscall.h>
|
||||
#include <errno.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
|
||||
/* ----- global defines ----------------------------------------------- */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define bit_dbg(level, dev, format, args...) \
|
||||
do { \
|
||||
if (i2c_debug >= level) \
|
||||
dev_dbg(dev, format, ##args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define bit_dbg(level, dev, format, args...) \
|
||||
do {} while (0)
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/* ----- global variables --------------------------------------------- */
|
||||
|
||||
static int bit_test; /* see if the line-setting functions work */
|
||||
|
||||
|
||||
/* --- setting states on the bus with the right timing: --------------- */
|
||||
|
||||
#define setsda(adap, val) adap->setsda(adap->data, val)
|
||||
#define setscl(adap, val) adap->setscl(adap->data, val)
|
||||
#define getsda(adap) adap->getsda(adap->data)
|
||||
#define getscl(adap) adap->getscl(adap->data)
|
||||
|
||||
static inline void sdalo(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
setsda(adap, 0);
|
||||
udelay((adap->udelay + 1) / 2);
|
||||
}
|
||||
|
||||
static inline void sdahi(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
setsda(adap, 1);
|
||||
udelay((adap->udelay + 1) / 2);
|
||||
}
|
||||
|
||||
static inline void scllo(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
setscl(adap, 0);
|
||||
udelay(adap->udelay / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Raise scl line, and do checking for delays. This is necessary for slower
|
||||
* devices.
|
||||
*/
|
||||
static int sclhi(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
unsigned long start;
|
||||
|
||||
setscl(adap, 1);
|
||||
|
||||
/* Not all adapters have scl sense line... */
|
||||
if (!adap->getscl)
|
||||
goto done;
|
||||
|
||||
// start = jiffies;
|
||||
while (!getscl(adap)) {
|
||||
/* This hw knows how to read the clock line, so we wait
|
||||
* until it actually gets high. This is safer as some
|
||||
* chips may hold it low ("clock stretching") while they
|
||||
* are processing data internally.
|
||||
*/
|
||||
// if (time_after(jiffies, start + adap->timeout))
|
||||
// return -ETIMEDOUT;
|
||||
|
||||
udelay(adap->udelay);
|
||||
|
||||
// cond_resched();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (jiffies != start && i2c_debug >= 3)
|
||||
pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
|
||||
"high\n", jiffies - start);
|
||||
#endif
|
||||
|
||||
done:
|
||||
udelay(adap->udelay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* --- other auxiliary functions -------------------------------------- */
|
||||
static void i2c_start(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
/* assert: scl, sda are high */
|
||||
setsda(adap, 0);
|
||||
udelay(adap->udelay);
|
||||
scllo(adap);
|
||||
}
|
||||
|
||||
static void i2c_repstart(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
/* assert: scl is low */
|
||||
sdahi(adap);
|
||||
sclhi(adap);
|
||||
setsda(adap, 0);
|
||||
udelay(adap->udelay);
|
||||
scllo(adap);
|
||||
}
|
||||
|
||||
|
||||
static void i2c_stop(struct i2c_algo_bit_data *adap)
|
||||
{
|
||||
/* assert: scl is low */
|
||||
sdalo(adap);
|
||||
sclhi(adap);
|
||||
setsda(adap, 1);
|
||||
udelay(adap->udelay);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* send a byte without start cond., look for arbitration,
|
||||
check ackn. from slave */
|
||||
/* returns:
|
||||
* 1 if the device acknowledged
|
||||
* 0 if the device did not ack
|
||||
* -ETIMEDOUT if an error occurred (while raising the scl line)
|
||||
*/
|
||||
static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
|
||||
{
|
||||
int i;
|
||||
int sb;
|
||||
int ack;
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
|
||||
/* assert: scl is low */
|
||||
for (i = 7; i >= 0; i--) {
|
||||
sb = (c >> i) & 1;
|
||||
setsda(adap, sb);
|
||||
udelay((adap->udelay + 1) / 2);
|
||||
if (sclhi(adap) < 0) { /* timed out */
|
||||
// bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
|
||||
// "timeout at bit #%d\n", (int)c, i);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/* FIXME do arbitration here:
|
||||
* if (sb && !getsda(adap)) -> ouch! Get out of here.
|
||||
*
|
||||
* Report a unique code, so higher level code can retry
|
||||
* the whole (combined) message and *NOT* issue STOP.
|
||||
*/
|
||||
scllo(adap);
|
||||
}
|
||||
sdahi(adap);
|
||||
if (sclhi(adap) < 0) { /* timeout */
|
||||
// bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
|
||||
// "timeout at ack\n", (int)c);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* read ack: SDA should be pulled down by slave, or it may
|
||||
* NAK (usually to report problems with the data we wrote).
|
||||
*/
|
||||
ack = !getsda(adap); /* ack: sda is pulled low -> success */
|
||||
// bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
|
||||
// ack ? "A" : "NA");
|
||||
|
||||
scllo(adap);
|
||||
return ack;
|
||||
/* assert: scl is low (sda undef) */
|
||||
}
|
||||
|
||||
|
||||
static int i2c_inb(struct i2c_adapter *i2c_adap)
|
||||
{
|
||||
/* read byte via i2c port, without start/stop sequence */
|
||||
/* acknowledge is sent in i2c_read. */
|
||||
int i;
|
||||
unsigned char indata = 0;
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
|
||||
/* assert: scl is low */
|
||||
sdahi(adap);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (sclhi(adap) < 0) { /* timeout */
|
||||
bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
|
||||
"#%d\n", 7 - i);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
indata *= 2;
|
||||
if (getsda(adap))
|
||||
indata |= 0x01;
|
||||
setscl(adap, 0);
|
||||
udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
|
||||
}
|
||||
/* assert: scl is low */
|
||||
return indata;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check for the adapter hardware - check the reaction of
|
||||
* the bus lines only if it seems to be idle.
|
||||
*/
|
||||
static int test_bus(struct i2c_algo_bit_data *adap, char *name)
|
||||
{
|
||||
int scl, sda;
|
||||
|
||||
if (adap->getscl == NULL)
|
||||
pr_info("%s: Testing SDA only, SCL is not readable\n", name);
|
||||
|
||||
sda = getsda(adap);
|
||||
scl = (adap->getscl == NULL) ? 1 : getscl(adap);
|
||||
if (!scl || !sda) {
|
||||
printk(KERN_WARNING "%s: bus seems to be busy\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
sdalo(adap);
|
||||
sda = getsda(adap);
|
||||
scl = (adap->getscl == NULL) ? 1 : getscl(adap);
|
||||
if (sda) {
|
||||
printk(KERN_WARNING "%s: SDA stuck high!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
if (!scl) {
|
||||
printk(KERN_WARNING "%s: SCL unexpected low "
|
||||
"while pulling SDA low!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
sdahi(adap);
|
||||
sda = getsda(adap);
|
||||
scl = (adap->getscl == NULL) ? 1 : getscl(adap);
|
||||
if (!sda) {
|
||||
printk(KERN_WARNING "%s: SDA stuck low!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
if (!scl) {
|
||||
printk(KERN_WARNING "%s: SCL unexpected low "
|
||||
"while pulling SDA high!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
scllo(adap);
|
||||
sda = getsda(adap);
|
||||
scl = (adap->getscl == NULL) ? 0 : getscl(adap);
|
||||
if (scl) {
|
||||
printk(KERN_WARNING "%s: SCL stuck high!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
if (!sda) {
|
||||
printk(KERN_WARNING "%s: SDA unexpected low "
|
||||
"while pulling SCL low!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
sclhi(adap);
|
||||
sda = getsda(adap);
|
||||
scl = (adap->getscl == NULL) ? 1 : getscl(adap);
|
||||
if (!scl) {
|
||||
printk(KERN_WARNING "%s: SCL stuck low!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
if (!sda) {
|
||||
printk(KERN_WARNING "%s: SDA unexpected low "
|
||||
"while pulling SCL high!\n", name);
|
||||
goto bailout;
|
||||
}
|
||||
pr_info("%s: Test OK\n", name);
|
||||
return 0;
|
||||
bailout:
|
||||
sdahi(adap);
|
||||
sclhi(adap);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* ----- Utility functions
|
||||
*/
|
||||
|
||||
/* try_address tries to contact a chip for a number of
|
||||
* times before it gives up.
|
||||
* return values:
|
||||
* 1 chip answered
|
||||
* 0 chip did not answer
|
||||
* -x transmission error
|
||||
*/
|
||||
static int try_address(struct i2c_adapter *i2c_adap,
|
||||
unsigned char addr, int retries)
|
||||
{
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i <= retries; i++) {
|
||||
ret = i2c_outb(i2c_adap, addr);
|
||||
if (ret == 1 || i == retries)
|
||||
break;
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
|
||||
i2c_stop(adap);
|
||||
udelay(adap->udelay);
|
||||
// yield();
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
|
||||
i2c_start(adap);
|
||||
}
|
||||
if (i && ret)
|
||||
bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
|
||||
"0x%02x: %s\n", i + 1,
|
||||
addr & 1 ? "read from" : "write to", addr >> 1,
|
||||
ret == 1 ? "success" : "failed, timeout?");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
|
||||
{
|
||||
const unsigned char *temp = msg->buf;
|
||||
int count = msg->len;
|
||||
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
|
||||
int retval;
|
||||
int wrcount = 0;
|
||||
|
||||
while (count > 0) {
|
||||
retval = i2c_outb(i2c_adap, *temp);
|
||||
|
||||
/* OK/ACK; or ignored NAK */
|
||||
if ((retval > 0) || (nak_ok && (retval == 0))) {
|
||||
count--;
|
||||
temp++;
|
||||
wrcount++;
|
||||
|
||||
/* A slave NAKing the master means the slave didn't like
|
||||
* something about the data it saw. For example, maybe
|
||||
* the SMBus PEC was wrong.
|
||||
*/
|
||||
} else if (retval == 0) {
|
||||
// dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
|
||||
return -EIO;
|
||||
|
||||
/* Timeout; or (someday) lost arbitration
|
||||
*
|
||||
* FIXME Lost ARB implies retrying the transaction from
|
||||
* the first message, after the "winning" master issues
|
||||
* its STOP. As a rule, upper layer code has no reason
|
||||
* to know or care about this ... it is *NOT* an error.
|
||||
*/
|
||||
} else {
|
||||
// dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
|
||||
// retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return wrcount;
|
||||
}
|
||||
|
||||
static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
|
||||
{
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
|
||||
/* assert: sda is high */
|
||||
if (is_ack) /* send ack */
|
||||
setsda(adap, 0);
|
||||
udelay((adap->udelay + 1) / 2);
|
||||
if (sclhi(adap) < 0) { /* timeout */
|
||||
// dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
|
||||
// return -ETIMEDOUT;
|
||||
}
|
||||
scllo(adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
|
||||
{
|
||||
int inval;
|
||||
int rdcount = 0; /* counts bytes read */
|
||||
unsigned char *temp = msg->buf;
|
||||
int count = msg->len;
|
||||
const unsigned flags = msg->flags;
|
||||
|
||||
while (count > 0) {
|
||||
inval = i2c_inb(i2c_adap);
|
||||
if (inval >= 0) {
|
||||
*temp = inval;
|
||||
rdcount++;
|
||||
} else { /* read timed out */
|
||||
break;
|
||||
}
|
||||
|
||||
temp++;
|
||||
count--;
|
||||
|
||||
/* Some SMBus transactions require that we receive the
|
||||
transaction length as the first read byte. */
|
||||
if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
|
||||
if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
|
||||
if (!(flags & I2C_M_NO_RD_ACK))
|
||||
acknak(i2c_adap, 0);
|
||||
// dev_err(&i2c_adap->dev, "readbytes: invalid "
|
||||
// "block length (%d)\n", inval);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
/* The original count value accounts for the extra
|
||||
bytes, that is, either 1 for a regular transaction,
|
||||
or 2 for a PEC transaction. */
|
||||
count += inval;
|
||||
msg->len += inval;
|
||||
}
|
||||
|
||||
// bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
|
||||
// inval,
|
||||
// (flags & I2C_M_NO_RD_ACK)
|
||||
// ? "(no ack/nak)"
|
||||
// : (count ? "A" : "NA"));
|
||||
|
||||
if (!(flags & I2C_M_NO_RD_ACK)) {
|
||||
inval = acknak(i2c_adap, count);
|
||||
if (inval < 0)
|
||||
return inval;
|
||||
}
|
||||
}
|
||||
return rdcount;
|
||||
}
|
||||
|
||||
/* doAddress initiates the transfer by generating the start condition (in
|
||||
* try_address) and transmits the address in the necessary format to handle
|
||||
* reads, writes as well as 10bit-addresses.
|
||||
* returns:
|
||||
* 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
|
||||
* -x an error occurred (like: -EREMOTEIO if the device did not answer, or
|
||||
* -ETIMEDOUT, for example if the lines are stuck...)
|
||||
*/
|
||||
static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
|
||||
{
|
||||
unsigned short flags = msg->flags;
|
||||
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
|
||||
unsigned char addr;
|
||||
int ret, retries;
|
||||
|
||||
retries = nak_ok ? 0 : i2c_adap->retries;
|
||||
|
||||
if (flags & I2C_M_TEN) {
|
||||
/* a ten bit address */
|
||||
addr = 0xf0 | ((msg->addr >> 7) & 0x03);
|
||||
bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
|
||||
/* try extended address code...*/
|
||||
ret = try_address(i2c_adap, addr, retries);
|
||||
if ((ret != 1) && !nak_ok) {
|
||||
// dev_err(&i2c_adap->dev,
|
||||
// "died at extended address code\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
/* the remaining 8 bit address */
|
||||
ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
|
||||
if ((ret != 1) && !nak_ok) {
|
||||
/* the chip did not ack / xmission error occurred */
|
||||
// dev_err(&i2c_adap->dev, "died at 2nd address code\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
if (flags & I2C_M_RD) {
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting repeated "
|
||||
"start condition\n");
|
||||
i2c_repstart(adap);
|
||||
/* okay, now switch into reading mode */
|
||||
addr |= 0x01;
|
||||
ret = try_address(i2c_adap, addr, retries);
|
||||
if ((ret != 1) && !nak_ok) {
|
||||
// dev_err(&i2c_adap->dev,
|
||||
// "died at repeated address code\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
} else { /* normal 7bit address */
|
||||
addr = msg->addr << 1;
|
||||
if (flags & I2C_M_RD)
|
||||
addr |= 1;
|
||||
if (flags & I2C_M_REV_DIR_ADDR)
|
||||
addr ^= 1;
|
||||
ret = try_address(i2c_adap, addr, retries);
|
||||
if ((ret != 1) && !nak_ok)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bit_xfer(struct i2c_adapter *i2c_adap,
|
||||
struct i2c_msg msgs[], int num)
|
||||
{
|
||||
struct i2c_msg *pmsg;
|
||||
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
|
||||
int i, ret;
|
||||
unsigned short nak_ok;
|
||||
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
|
||||
i2c_start(adap);
|
||||
for (i = 0; i < num; i++) {
|
||||
pmsg = &msgs[i];
|
||||
nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
|
||||
if (!(pmsg->flags & I2C_M_NOSTART)) {
|
||||
if (i) {
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting "
|
||||
"repeated start condition\n");
|
||||
i2c_repstart(adap);
|
||||
}
|
||||
ret = bit_doAddress(i2c_adap, pmsg);
|
||||
if ((ret != 0) && !nak_ok) {
|
||||
bit_dbg(1, &i2c_adap->dev, "NAK from "
|
||||
"device addr 0x%02x msg #%d\n",
|
||||
msgs[i].addr, i);
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
if (pmsg->flags & I2C_M_RD) {
|
||||
/* read bytes into buffer*/
|
||||
ret = readbytes(i2c_adap, pmsg);
|
||||
if (ret >= 1)
|
||||
bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n",
|
||||
ret, ret == 1 ? "" : "s");
|
||||
if (ret < pmsg->len) {
|
||||
if (ret >= 0)
|
||||
ret = -EREMOTEIO;
|
||||
goto bailout;
|
||||
}
|
||||
} else {
|
||||
/* write bytes from buffer */
|
||||
ret = sendbytes(i2c_adap, pmsg);
|
||||
if (ret >= 1)
|
||||
bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n",
|
||||
ret, ret == 1 ? "" : "s");
|
||||
if (ret < pmsg->len) {
|
||||
if (ret >= 0)
|
||||
ret = -EREMOTEIO;
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = i;
|
||||
|
||||
bailout:
|
||||
bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
|
||||
i2c_stop(adap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 bit_func(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
|
||||
I2C_FUNC_SMBUS_READ_BLOCK_DATA |
|
||||
I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
|
||||
I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
|
||||
}
|
||||
|
||||
|
||||
/* -----exported algorithm data: ------------------------------------- */
|
||||
|
||||
static const struct i2c_algorithm i2c_bit_algo = {
|
||||
.master_xfer = bit_xfer,
|
||||
.functionality = bit_func,
|
||||
};
|
||||
|
||||
/*
|
||||
* registering functions to load algorithms at runtime
|
||||
*/
|
||||
static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_algo_bit_data *bit_adap = adap->algo_data;
|
||||
|
||||
// if (bit_test) {
|
||||
// int ret = test_bus(bit_adap, adap->name);
|
||||
// if (ret < 0)
|
||||
// return -ENODEV;
|
||||
// }
|
||||
|
||||
/* register new adapter to i2c module... */
|
||||
adap->algo = &i2c_bit_algo;
|
||||
adap->retries = 3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_bit_add_bus(struct i2c_adapter *adap)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = i2c_bit_prepare_bus(adap);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0; //i2c_add_adapter(adap);
|
||||
}
|
||||
|
||||
108
drivers/video/drm/i2c/i2c-core.c
Normal file
108
drivers/video/drm/i2c/i2c-core.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/* i2c-core.c - a device driver for the iic-bus interface */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Copyright (C) 1995-99 Simon G. Vogl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
|
||||
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
|
||||
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
|
||||
Jean Delvare <khali@linux-fr.org> */
|
||||
|
||||
#include <types.h>
|
||||
#include <list.h>
|
||||
#include <errno.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <syscall.h>
|
||||
|
||||
|
||||
/**
|
||||
* i2c_transfer - execute a single or combined I2C message
|
||||
* @adap: Handle to I2C bus
|
||||
* @msgs: One or more messages to execute before STOP is issued to
|
||||
* terminate the operation; each message begins with a START.
|
||||
* @num: Number of messages to be executed.
|
||||
*
|
||||
* Returns negative errno, else the number of messages executed.
|
||||
*
|
||||
* Note that there is no requirement that each message be sent to
|
||||
* the same slave address, although that is the most common model.
|
||||
*/
|
||||
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
unsigned long orig_jiffies;
|
||||
int ret, try;
|
||||
|
||||
/* REVISIT the fault reporting model here is weak:
|
||||
*
|
||||
* - When we get an error after receiving N bytes from a slave,
|
||||
* there is no way to report "N".
|
||||
*
|
||||
* - When we get a NAK after transmitting N bytes to a slave,
|
||||
* there is no way to report "N" ... or to let the master
|
||||
* continue executing the rest of this combined message, if
|
||||
* that's the appropriate response.
|
||||
*
|
||||
* - When for example "num" is two and we successfully complete
|
||||
* the first message but get an error part way through the
|
||||
* second, it's unclear whether that should be reported as
|
||||
* one (discarding status on the second message) or errno
|
||||
* (discarding status on the first one).
|
||||
*/
|
||||
|
||||
if (adap->algo->master_xfer) {
|
||||
#ifdef DEBUG
|
||||
for (ret = 0; ret < num; ret++) {
|
||||
dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
|
||||
"len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
|
||||
? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
|
||||
(msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
// if (in_atomic() || irqs_disabled()) {
|
||||
// ret = mutex_trylock(&adap->bus_lock);
|
||||
// if (!ret)
|
||||
// /* I2C activity is ongoing. */
|
||||
// return -EAGAIN;
|
||||
// } else {
|
||||
// mutex_lock_nested(&adap->bus_lock, adap->level);
|
||||
// }
|
||||
|
||||
/* Retry automatically on arbitration loss */
|
||||
// orig_jiffies = jiffies;
|
||||
for (ret = 0, try = 0; try <= adap->retries; try++) {
|
||||
ret = adap->algo->master_xfer(adap, msgs, num);
|
||||
if (ret != -EAGAIN)
|
||||
break;
|
||||
// if (time_after(jiffies, orig_jiffies + adap->timeout))
|
||||
// break;
|
||||
delay(1);
|
||||
}
|
||||
// mutex_unlock(&adap->bus_lock);
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
// dev_dbg(&adap->dev, "I2C level transfers not supported\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_transfer);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1064
drivers/video/drm/idr.c
Normal file
1064
drivers/video/drm/idr.c
Normal file
File diff suppressed because it is too large
Load Diff
744
drivers/video/drm/include/drm.h
Normal file
744
drivers/video/drm/include/drm.h
Normal file
@@ -0,0 +1,744 @@
|
||||
/**
|
||||
* \file drm.h
|
||||
* Header for the Direct Rendering Manager
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
* \par Acknowledgments:
|
||||
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 (including the next
|
||||
* paragraph) 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
|
||||
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
#ifndef _DRM_H_
|
||||
#define _DRM_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <errno-base.h>
|
||||
|
||||
//#include <asm/ioctl.h> /* For _IO* macros */
|
||||
|
||||
#define DRM_MAJOR 226
|
||||
#define DRM_MAX_MINOR 15
|
||||
|
||||
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
|
||||
#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
|
||||
#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
|
||||
#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
|
||||
|
||||
#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
|
||||
#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
|
||||
#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
|
||||
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
|
||||
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
|
||||
|
||||
typedef unsigned int drm_handle_t;
|
||||
typedef unsigned int drm_context_t;
|
||||
typedef unsigned int drm_drawable_t;
|
||||
typedef unsigned int drm_magic_t;
|
||||
|
||||
/**
|
||||
* Cliprect.
|
||||
*
|
||||
* \warning: If you change this structure, make sure you change
|
||||
* XF86DRIClipRectRec in the server as well
|
||||
*
|
||||
* \note KW: Actually it's illegal to change either for
|
||||
* backwards-compatibility reasons.
|
||||
*/
|
||||
struct drm_clip_rect {
|
||||
unsigned short x1;
|
||||
unsigned short y1;
|
||||
unsigned short x2;
|
||||
unsigned short y2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawable information.
|
||||
*/
|
||||
struct drm_drawable_info {
|
||||
unsigned int num_rects;
|
||||
struct drm_clip_rect *rects;
|
||||
};
|
||||
|
||||
/**
|
||||
* Texture region,
|
||||
*/
|
||||
struct drm_tex_region {
|
||||
unsigned char next;
|
||||
unsigned char prev;
|
||||
unsigned char in_use;
|
||||
unsigned char padding;
|
||||
unsigned int age;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hardware lock.
|
||||
*
|
||||
* The lock structure is a simple cache-line aligned integer. To avoid
|
||||
* processor bus contention on a multiprocessor system, there should not be any
|
||||
* other data stored in the same cache line.
|
||||
*/
|
||||
struct drm_hw_lock {
|
||||
__volatile__ unsigned int lock; /**< lock variable */
|
||||
char padding[60]; /**< Pad to cache line */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_VERSION ioctl argument type.
|
||||
*
|
||||
* \sa drmGetVersion().
|
||||
*/
|
||||
struct drm_version {
|
||||
int version_major; /**< Major version */
|
||||
int version_minor; /**< Minor version */
|
||||
int version_patchlevel; /**< Patch level */
|
||||
size_t name_len; /**< Length of name buffer */
|
||||
char __user *name; /**< Name of driver */
|
||||
size_t date_len; /**< Length of date buffer */
|
||||
char __user *date; /**< User-space buffer to hold date */
|
||||
size_t desc_len; /**< Length of desc buffer */
|
||||
char __user *desc; /**< User-space buffer to hold desc */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
|
||||
*
|
||||
* \sa drmGetBusid() and drmSetBusId().
|
||||
*/
|
||||
struct drm_unique {
|
||||
size_t unique_len; /**< Length of unique */
|
||||
char __user *unique; /**< Unique name for driver instantiation */
|
||||
};
|
||||
|
||||
struct drm_list {
|
||||
int count; /**< Length of user-space structures */
|
||||
struct drm_version __user *version;
|
||||
};
|
||||
|
||||
struct drm_block {
|
||||
int unused;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_CONTROL ioctl argument type.
|
||||
*
|
||||
* \sa drmCtlInstHandler() and drmCtlUninstHandler().
|
||||
*/
|
||||
struct drm_control {
|
||||
enum {
|
||||
DRM_ADD_COMMAND,
|
||||
DRM_RM_COMMAND,
|
||||
DRM_INST_HANDLER,
|
||||
DRM_UNINST_HANDLER
|
||||
} func;
|
||||
int irq;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type of memory to map.
|
||||
*/
|
||||
enum drm_map_type {
|
||||
_DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /**< no caching, no core dump */
|
||||
_DRM_SHM = 2, /**< shared, cached */
|
||||
_DRM_AGP = 3, /**< AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
|
||||
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
|
||||
_DRM_GEM = 6, /**< GEM object */
|
||||
};
|
||||
|
||||
/**
|
||||
* Memory mapping flags.
|
||||
*/
|
||||
enum drm_map_flags {
|
||||
_DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
|
||||
_DRM_READ_ONLY = 0x02,
|
||||
_DRM_LOCKED = 0x04, /**< shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /**< kernel requires access */
|
||||
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40, /**< Removable mapping */
|
||||
_DRM_DRIVER = 0x80 /**< Managed by driver */
|
||||
};
|
||||
|
||||
struct drm_ctx_priv_map {
|
||||
unsigned int ctx_id; /**< Context requesting private mapping */
|
||||
void *handle; /**< Handle of map */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
|
||||
* argument type.
|
||||
*
|
||||
* \sa drmAddMap().
|
||||
*/
|
||||
struct drm_map {
|
||||
unsigned long offset; /**< Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /**< Requested physical size (bytes) */
|
||||
enum drm_map_type type; /**< Type of memory to map */
|
||||
enum drm_map_flags flags; /**< Flags */
|
||||
void *handle; /**< User-space: "Handle" to pass to mmap() */
|
||||
/**< Kernel-space: kernel-virtual address */
|
||||
int mtrr; /**< MTRR slot used */
|
||||
/* Private data */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_CLIENT ioctl argument type.
|
||||
*/
|
||||
struct drm_client {
|
||||
int idx; /**< Which client desired? */
|
||||
int auth; /**< Is client authenticated? */
|
||||
unsigned long pid; /**< Process ID */
|
||||
unsigned long uid; /**< User ID */
|
||||
unsigned long magic; /**< Magic */
|
||||
unsigned long iocs; /**< Ioctl count */
|
||||
};
|
||||
|
||||
enum drm_stat_type {
|
||||
_DRM_STAT_LOCK,
|
||||
_DRM_STAT_OPENS,
|
||||
_DRM_STAT_CLOSES,
|
||||
_DRM_STAT_IOCTLS,
|
||||
_DRM_STAT_LOCKS,
|
||||
_DRM_STAT_UNLOCKS,
|
||||
_DRM_STAT_VALUE, /**< Generic value */
|
||||
_DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */
|
||||
_DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */
|
||||
|
||||
_DRM_STAT_IRQ, /**< IRQ */
|
||||
_DRM_STAT_PRIMARY, /**< Primary DMA bytes */
|
||||
_DRM_STAT_SECONDARY, /**< Secondary DMA bytes */
|
||||
_DRM_STAT_DMA, /**< DMA */
|
||||
_DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
|
||||
_DRM_STAT_MISSED /**< Missed DMA opportunity */
|
||||
/* Add to the *END* of the list */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_STATS ioctl argument type.
|
||||
*/
|
||||
struct drm_stats {
|
||||
unsigned long count;
|
||||
struct {
|
||||
unsigned long value;
|
||||
enum drm_stat_type type;
|
||||
} data[15];
|
||||
};
|
||||
|
||||
/**
|
||||
* Hardware locking flags.
|
||||
*/
|
||||
enum drm_lock_flags {
|
||||
_DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
|
||||
_DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
|
||||
_DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
|
||||
_DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
|
||||
/* These *HALT* flags aren't supported yet
|
||||
-- they will be used to support the
|
||||
full-screen DGA-like mode. */
|
||||
_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
|
||||
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
|
||||
*
|
||||
* \sa drmGetLock() and drmUnlock().
|
||||
*/
|
||||
struct drm_lock {
|
||||
int context;
|
||||
enum drm_lock_flags flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* DMA flags
|
||||
*
|
||||
* \warning
|
||||
* These values \e must match xf86drm.h.
|
||||
*
|
||||
* \sa drm_dma.
|
||||
*/
|
||||
enum drm_dma_flags {
|
||||
/* Flags for DMA buffer dispatch */
|
||||
_DRM_DMA_BLOCK = 0x01, /**<
|
||||
* Block until buffer dispatched.
|
||||
*
|
||||
* \note The buffer may not yet have
|
||||
* been processed by the hardware --
|
||||
* getting a hardware lock with the
|
||||
* hardware quiescent will ensure
|
||||
* that the buffer has been
|
||||
* processed.
|
||||
*/
|
||||
_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
|
||||
_DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
|
||||
|
||||
/* Flags for DMA buffer request */
|
||||
_DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
|
||||
_DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
|
||||
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
|
||||
*
|
||||
* \sa drmAddBufs().
|
||||
*/
|
||||
struct drm_buf_desc {
|
||||
int count; /**< Number of buffers of this size */
|
||||
int size; /**< Size in bytes */
|
||||
int low_mark; /**< Low water mark */
|
||||
int high_mark; /**< High water mark */
|
||||
enum {
|
||||
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
|
||||
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
|
||||
_DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
|
||||
_DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
|
||||
} flags;
|
||||
unsigned long agp_start; /**<
|
||||
* Start address of where the AGP buffers are
|
||||
* in the AGP aperture
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_INFO_BUFS ioctl argument type.
|
||||
*/
|
||||
struct drm_buf_info {
|
||||
int count; /**< Entries in list */
|
||||
struct drm_buf_desc __user *list;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_FREE_BUFS ioctl argument type.
|
||||
*/
|
||||
struct drm_buf_free {
|
||||
int count;
|
||||
int __user *list;
|
||||
};
|
||||
|
||||
/**
|
||||
* Buffer information
|
||||
*
|
||||
* \sa drm_buf_map.
|
||||
*/
|
||||
struct drm_buf_pub {
|
||||
int idx; /**< Index into the master buffer list */
|
||||
int total; /**< Buffer size */
|
||||
int used; /**< Amount of buffer in use (for DMA) */
|
||||
void __user *address; /**< Address of buffer */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_MAP_BUFS ioctl argument type.
|
||||
*/
|
||||
struct drm_buf_map {
|
||||
int count; /**< Length of the buffer list */
|
||||
void __user *virtual; /**< Mmap'd area in user-virtual */
|
||||
struct drm_buf_pub __user *list; /**< Buffer information */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_DMA ioctl argument type.
|
||||
*
|
||||
* Indices here refer to the offset into the buffer list in drm_buf_get.
|
||||
*
|
||||
* \sa drmDMA().
|
||||
*/
|
||||
struct drm_dma {
|
||||
int context; /**< Context handle */
|
||||
int send_count; /**< Number of buffers to send */
|
||||
int __user *send_indices; /**< List of handles to buffers */
|
||||
int __user *send_sizes; /**< Lengths of data to send */
|
||||
enum drm_dma_flags flags; /**< Flags */
|
||||
int request_count; /**< Number of buffers requested */
|
||||
int request_size; /**< Desired size for buffers */
|
||||
int __user *request_indices; /**< Buffer information */
|
||||
int __user *request_sizes;
|
||||
int granted_count; /**< Number of buffers granted */
|
||||
};
|
||||
|
||||
enum drm_ctx_flags {
|
||||
_DRM_CONTEXT_PRESERVED = 0x01,
|
||||
_DRM_CONTEXT_2DONLY = 0x02
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_CTX ioctl argument type.
|
||||
*
|
||||
* \sa drmCreateContext() and drmDestroyContext().
|
||||
*/
|
||||
struct drm_ctx {
|
||||
drm_context_t handle;
|
||||
enum drm_ctx_flags flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_RES_CTX ioctl argument type.
|
||||
*/
|
||||
struct drm_ctx_res {
|
||||
int count;
|
||||
struct drm_ctx __user *contexts;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
|
||||
*/
|
||||
struct drm_draw {
|
||||
drm_drawable_t handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_UPDATE_DRAW ioctl argument type.
|
||||
*/
|
||||
typedef enum {
|
||||
DRM_DRAWABLE_CLIPRECTS,
|
||||
} drm_drawable_info_type_t;
|
||||
|
||||
struct drm_update_draw {
|
||||
drm_drawable_t handle;
|
||||
unsigned int type;
|
||||
unsigned int num;
|
||||
unsigned long long data;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
|
||||
*/
|
||||
struct drm_auth {
|
||||
drm_magic_t magic;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
|
||||
*
|
||||
* \sa drmGetInterruptFromBusID().
|
||||
*/
|
||||
struct drm_irq_busid {
|
||||
int irq; /**< IRQ number */
|
||||
int busnum; /**< bus number */
|
||||
int devnum; /**< device number */
|
||||
int funcnum; /**< function number */
|
||||
};
|
||||
|
||||
enum drm_vblank_seq_type {
|
||||
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
||||
_DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
|
||||
_DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
|
||||
_DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
|
||||
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */
|
||||
};
|
||||
|
||||
#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
|
||||
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
|
||||
_DRM_VBLANK_NEXTONMISS)
|
||||
|
||||
struct drm_wait_vblank_request {
|
||||
enum drm_vblank_seq_type type;
|
||||
unsigned int sequence;
|
||||
unsigned long signal;
|
||||
};
|
||||
|
||||
struct drm_wait_vblank_reply {
|
||||
enum drm_vblank_seq_type type;
|
||||
unsigned int sequence;
|
||||
long tval_sec;
|
||||
long tval_usec;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
|
||||
*
|
||||
* \sa drmWaitVBlank().
|
||||
*/
|
||||
union drm_wait_vblank {
|
||||
struct drm_wait_vblank_request request;
|
||||
struct drm_wait_vblank_reply reply;
|
||||
};
|
||||
|
||||
#define _DRM_PRE_MODESET 1
|
||||
#define _DRM_POST_MODESET 2
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_MODESET_CTL ioctl argument type
|
||||
*
|
||||
* \sa drmModesetCtl().
|
||||
*/
|
||||
struct drm_modeset_ctl {
|
||||
__u32 crtc;
|
||||
__u32 cmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
|
||||
*
|
||||
* \sa drmAgpEnable().
|
||||
*/
|
||||
struct drm_agp_mode {
|
||||
unsigned long mode; /**< AGP mode */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
|
||||
*
|
||||
* \sa drmAgpAlloc() and drmAgpFree().
|
||||
*/
|
||||
struct drm_agp_buffer {
|
||||
unsigned long size; /**< In bytes -- will round to page boundary */
|
||||
unsigned long handle; /**< Used for binding / unbinding */
|
||||
unsigned long type; /**< Type of memory to allocate */
|
||||
unsigned long physical; /**< Physical used by i810 */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
|
||||
*
|
||||
* \sa drmAgpBind() and drmAgpUnbind().
|
||||
*/
|
||||
struct drm_agp_binding {
|
||||
unsigned long handle; /**< From drm_agp_buffer */
|
||||
unsigned long offset; /**< In bytes -- will round to page boundary */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_INFO ioctl argument type.
|
||||
*
|
||||
* \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
|
||||
* drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
|
||||
* drmAgpVendorId() and drmAgpDeviceId().
|
||||
*/
|
||||
struct drm_agp_info {
|
||||
int agp_version_major;
|
||||
int agp_version_minor;
|
||||
unsigned long mode;
|
||||
unsigned long aperture_base; /* physical address */
|
||||
unsigned long aperture_size; /* bytes */
|
||||
unsigned long memory_allowed; /* bytes */
|
||||
unsigned long memory_used;
|
||||
|
||||
/* PCI information */
|
||||
unsigned short id_vendor;
|
||||
unsigned short id_device;
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_SG_ALLOC ioctl argument type.
|
||||
*/
|
||||
struct drm_scatter_gather {
|
||||
unsigned long size; /**< In bytes -- will round to page boundary */
|
||||
unsigned long handle; /**< Used for mapping / unmapping */
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_SET_VERSION ioctl argument type.
|
||||
*/
|
||||
struct drm_set_version {
|
||||
int drm_di_major;
|
||||
int drm_di_minor;
|
||||
int drm_dd_major;
|
||||
int drm_dd_minor;
|
||||
};
|
||||
|
||||
/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
|
||||
struct drm_gem_close {
|
||||
/** Handle of the object to be closed. */
|
||||
__u32 handle;
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/** DRM_IOCTL_GEM_FLINK ioctl argument type */
|
||||
struct drm_gem_flink {
|
||||
/** Handle for the object being named */
|
||||
__u32 handle;
|
||||
|
||||
/** Returned global name */
|
||||
__u32 name;
|
||||
};
|
||||
|
||||
/** DRM_IOCTL_GEM_OPEN ioctl argument type */
|
||||
struct drm_gem_open {
|
||||
/** Name of object being opened */
|
||||
__u32 name;
|
||||
|
||||
/** Returned handle for the object */
|
||||
__u32 handle;
|
||||
|
||||
/** Returned size of the object */
|
||||
__u64 size;
|
||||
};
|
||||
|
||||
#include "drm_mode.h"
|
||||
|
||||
/*
|
||||
#define DRM_IOCTL_BASE 'd'
|
||||
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
|
||||
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
|
||||
#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
|
||||
#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
|
||||
|
||||
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
|
||||
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
|
||||
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth)
|
||||
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
|
||||
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
|
||||
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
|
||||
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
|
||||
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
|
||||
#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
|
||||
#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
|
||||
#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
|
||||
#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
|
||||
|
||||
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
|
||||
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
|
||||
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
|
||||
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block)
|
||||
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control)
|
||||
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map)
|
||||
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
|
||||
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc)
|
||||
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info)
|
||||
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map)
|
||||
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free)
|
||||
|
||||
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map)
|
||||
|
||||
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
|
||||
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
|
||||
|
||||
#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
|
||||
#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
|
||||
|
||||
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
|
||||
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
|
||||
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
|
||||
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx)
|
||||
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx)
|
||||
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx)
|
||||
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res)
|
||||
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw)
|
||||
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw)
|
||||
#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma)
|
||||
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock)
|
||||
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
|
||||
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
|
||||
|
||||
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
|
||||
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
|
||||
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode)
|
||||
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info)
|
||||
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
|
||||
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer)
|
||||
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
|
||||
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
|
||||
|
||||
#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
|
||||
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
|
||||
|
||||
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
|
||||
|
||||
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
|
||||
|
||||
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
|
||||
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
|
||||
#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
|
||||
#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
|
||||
#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
|
||||
#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
|
||||
#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
|
||||
#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
|
||||
#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd)
|
||||
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
|
||||
|
||||
#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
|
||||
#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
|
||||
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
|
||||
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
|
||||
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
|
||||
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Device specific ioctls should only be in their respective headers
|
||||
* The device specific ioctl range is from 0x40 to 0x99.
|
||||
* Generic IOCTLS restart at 0xA0.
|
||||
*
|
||||
* \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
|
||||
* drmCommandReadWrite().
|
||||
*/
|
||||
#define DRM_COMMAND_BASE 0x40
|
||||
#define DRM_COMMAND_END 0xA0
|
||||
|
||||
/* typedef area */
|
||||
#ifndef __KERNEL__
|
||||
typedef struct drm_clip_rect drm_clip_rect_t;
|
||||
typedef struct drm_drawable_info drm_drawable_info_t;
|
||||
typedef struct drm_tex_region drm_tex_region_t;
|
||||
typedef struct drm_hw_lock drm_hw_lock_t;
|
||||
typedef struct drm_version drm_version_t;
|
||||
typedef struct drm_unique drm_unique_t;
|
||||
typedef struct drm_list drm_list_t;
|
||||
typedef struct drm_block drm_block_t;
|
||||
typedef struct drm_control drm_control_t;
|
||||
typedef enum drm_map_type drm_map_type_t;
|
||||
typedef enum drm_map_flags drm_map_flags_t;
|
||||
typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
|
||||
typedef struct drm_map drm_map_t;
|
||||
typedef struct drm_client drm_client_t;
|
||||
typedef enum drm_stat_type drm_stat_type_t;
|
||||
typedef struct drm_stats drm_stats_t;
|
||||
typedef enum drm_lock_flags drm_lock_flags_t;
|
||||
typedef struct drm_lock drm_lock_t;
|
||||
typedef enum drm_dma_flags drm_dma_flags_t;
|
||||
typedef struct drm_buf_desc drm_buf_desc_t;
|
||||
typedef struct drm_buf_info drm_buf_info_t;
|
||||
typedef struct drm_buf_free drm_buf_free_t;
|
||||
typedef struct drm_buf_pub drm_buf_pub_t;
|
||||
typedef struct drm_buf_map drm_buf_map_t;
|
||||
typedef struct drm_dma drm_dma_t;
|
||||
typedef union drm_wait_vblank drm_wait_vblank_t;
|
||||
typedef struct drm_agp_mode drm_agp_mode_t;
|
||||
typedef enum drm_ctx_flags drm_ctx_flags_t;
|
||||
typedef struct drm_ctx drm_ctx_t;
|
||||
typedef struct drm_ctx_res drm_ctx_res_t;
|
||||
typedef struct drm_draw drm_draw_t;
|
||||
typedef struct drm_update_draw drm_update_draw_t;
|
||||
typedef struct drm_auth drm_auth_t;
|
||||
typedef struct drm_irq_busid drm_irq_busid_t;
|
||||
typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
|
||||
|
||||
typedef struct drm_agp_buffer drm_agp_buffer_t;
|
||||
typedef struct drm_agp_binding drm_agp_binding_t;
|
||||
typedef struct drm_agp_info drm_agp_info_t;
|
||||
typedef struct drm_scatter_gather drm_scatter_gather_t;
|
||||
typedef struct drm_set_version drm_set_version_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1555
drivers/video/drm/include/drmP.h
Normal file
1555
drivers/video/drm/include/drmP.h
Normal file
File diff suppressed because it is too large
Load Diff
743
drivers/video/drm/include/drm_crtc.h
Normal file
743
drivers/video/drm/include/drm_crtc.h
Normal file
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright © 2007-2008 Dave Airlie
|
||||
* Copyright © 2007-2008 Intel Corporation
|
||||
* Jesse Barnes <jesse.barnes@intel.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.
|
||||
*/
|
||||
#ifndef __DRM_CRTC_H__
|
||||
#define __DRM_CRTC_H__
|
||||
|
||||
#include <linux/i2c.h>
|
||||
//#include <linux/spinlock.h>
|
||||
//#include <linux/types.h>
|
||||
#include <linux/idr.h>
|
||||
|
||||
//#include <linux/fb.h>
|
||||
|
||||
struct drm_device;
|
||||
struct drm_mode_set;
|
||||
struct drm_framebuffer;
|
||||
|
||||
|
||||
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
|
||||
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
|
||||
#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
|
||||
#define DRM_MODE_OBJECT_MODE 0xdededede
|
||||
#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
|
||||
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
|
||||
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
|
||||
|
||||
struct drm_mode_object {
|
||||
uint32_t id;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Note on terminology: here, for brevity and convenience, we refer to connector
|
||||
* control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
|
||||
* DVI, etc. And 'screen' refers to the whole of the visible display, which
|
||||
* may span multiple monitors (and therefore multiple CRTC and connector
|
||||
* structures).
|
||||
*/
|
||||
|
||||
enum drm_mode_status {
|
||||
MODE_OK = 0, /* Mode OK */
|
||||
MODE_HSYNC, /* hsync out of range */
|
||||
MODE_VSYNC, /* vsync out of range */
|
||||
MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
|
||||
MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
|
||||
MODE_BAD_WIDTH, /* requires an unsupported linepitch */
|
||||
MODE_NOMODE, /* no mode with a maching name */
|
||||
MODE_NO_INTERLACE, /* interlaced mode not supported */
|
||||
MODE_NO_DBLESCAN, /* doublescan mode not supported */
|
||||
MODE_NO_VSCAN, /* multiscan mode not supported */
|
||||
MODE_MEM, /* insufficient video memory */
|
||||
MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
|
||||
MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
|
||||
MODE_MEM_VIRT, /* insufficient video memory given virtual size */
|
||||
MODE_NOCLOCK, /* no fixed clock available */
|
||||
MODE_CLOCK_HIGH, /* clock required is too high */
|
||||
MODE_CLOCK_LOW, /* clock required is too low */
|
||||
MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
|
||||
MODE_BAD_HVALUE, /* horizontal timing was out of range */
|
||||
MODE_BAD_VVALUE, /* vertical timing was out of range */
|
||||
MODE_BAD_VSCAN, /* VScan value out of range */
|
||||
MODE_HSYNC_NARROW, /* horizontal sync too narrow */
|
||||
MODE_HSYNC_WIDE, /* horizontal sync too wide */
|
||||
MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
|
||||
MODE_HBLANK_WIDE, /* horizontal blanking too wide */
|
||||
MODE_VSYNC_NARROW, /* vertical sync too narrow */
|
||||
MODE_VSYNC_WIDE, /* vertical sync too wide */
|
||||
MODE_VBLANK_NARROW, /* vertical blanking too narrow */
|
||||
MODE_VBLANK_WIDE, /* vertical blanking too wide */
|
||||
MODE_PANEL, /* exceeds panel dimensions */
|
||||
MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
|
||||
MODE_ONE_WIDTH, /* only one width is supported */
|
||||
MODE_ONE_HEIGHT, /* only one height is supported */
|
||||
MODE_ONE_SIZE, /* only one resolution is supported */
|
||||
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
|
||||
MODE_UNVERIFIED = -3, /* mode needs to reverified */
|
||||
MODE_BAD = -2, /* unspecified reason */
|
||||
MODE_ERROR = -1 /* error condition */
|
||||
};
|
||||
|
||||
#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
|
||||
DRM_MODE_TYPE_CRTC_C)
|
||||
|
||||
#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
|
||||
.name = nm, .status = 0, .type = (t), .clock = (c), \
|
||||
.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
|
||||
.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
|
||||
.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
|
||||
.vscan = (vs), .flags = (f), .vrefresh = 0
|
||||
|
||||
#define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */
|
||||
|
||||
struct drm_display_mode {
|
||||
/* Header */
|
||||
struct list_head head;
|
||||
struct drm_mode_object base;
|
||||
|
||||
char name[DRM_DISPLAY_MODE_LEN];
|
||||
|
||||
int connector_count;
|
||||
enum drm_mode_status status;
|
||||
int type;
|
||||
|
||||
/* Proposed mode values */
|
||||
int clock;
|
||||
int hdisplay;
|
||||
int hsync_start;
|
||||
int hsync_end;
|
||||
int htotal;
|
||||
int hskew;
|
||||
int vdisplay;
|
||||
int vsync_start;
|
||||
int vsync_end;
|
||||
int vtotal;
|
||||
int vscan;
|
||||
unsigned int flags;
|
||||
|
||||
/* Addressable image size (may be 0 for projectors, etc.) */
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
|
||||
/* Actual mode we give to hw */
|
||||
int clock_index;
|
||||
int synth_clock;
|
||||
int crtc_hdisplay;
|
||||
int crtc_hblank_start;
|
||||
int crtc_hblank_end;
|
||||
int crtc_hsync_start;
|
||||
int crtc_hsync_end;
|
||||
int crtc_htotal;
|
||||
int crtc_hskew;
|
||||
int crtc_vdisplay;
|
||||
int crtc_vblank_start;
|
||||
int crtc_vblank_end;
|
||||
int crtc_vsync_start;
|
||||
int crtc_vsync_end;
|
||||
int crtc_vtotal;
|
||||
int crtc_hadjusted;
|
||||
int crtc_vadjusted;
|
||||
|
||||
/* Driver private mode info */
|
||||
int private_size;
|
||||
int *private;
|
||||
int private_flags;
|
||||
|
||||
int vrefresh;
|
||||
float hsync;
|
||||
};
|
||||
|
||||
enum drm_connector_status {
|
||||
connector_status_connected = 1,
|
||||
connector_status_disconnected = 2,
|
||||
connector_status_unknown = 3,
|
||||
};
|
||||
|
||||
enum subpixel_order {
|
||||
SubPixelUnknown = 0,
|
||||
SubPixelHorizontalRGB,
|
||||
SubPixelHorizontalBGR,
|
||||
SubPixelVerticalRGB,
|
||||
SubPixelVerticalBGR,
|
||||
SubPixelNone,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Describes a given display (e.g. CRT or flat panel) and its limitations.
|
||||
*/
|
||||
struct drm_display_info {
|
||||
char name[DRM_DISPLAY_INFO_LEN];
|
||||
/* Input info */
|
||||
bool serration_vsync;
|
||||
bool sync_on_green;
|
||||
bool composite_sync;
|
||||
bool separate_syncs;
|
||||
bool blank_to_black;
|
||||
unsigned char video_level;
|
||||
bool digital;
|
||||
/* Physical size */
|
||||
unsigned int width_mm;
|
||||
unsigned int height_mm;
|
||||
|
||||
/* Display parameters */
|
||||
unsigned char gamma; /* FIXME: storage format */
|
||||
bool gtf_supported;
|
||||
bool standard_color;
|
||||
enum {
|
||||
monochrome = 0,
|
||||
rgb,
|
||||
other,
|
||||
unknown,
|
||||
} display_type;
|
||||
bool active_off_supported;
|
||||
bool suspend_supported;
|
||||
bool standby_supported;
|
||||
|
||||
/* Color info FIXME: storage format */
|
||||
unsigned short redx, redy;
|
||||
unsigned short greenx, greeny;
|
||||
unsigned short bluex, bluey;
|
||||
unsigned short whitex, whitey;
|
||||
|
||||
/* Clock limits FIXME: storage format */
|
||||
unsigned int min_vfreq, max_vfreq;
|
||||
unsigned int min_hfreq, max_hfreq;
|
||||
unsigned int pixel_clock;
|
||||
|
||||
/* White point indices FIXME: storage format */
|
||||
unsigned int wpx1, wpy1;
|
||||
unsigned int wpgamma1;
|
||||
unsigned int wpx2, wpy2;
|
||||
unsigned int wpgamma2;
|
||||
|
||||
enum subpixel_order subpixel_order;
|
||||
|
||||
char *raw_edid; /* if any */
|
||||
};
|
||||
|
||||
struct drm_framebuffer_funcs {
|
||||
void (*destroy)(struct drm_framebuffer *framebuffer);
|
||||
int (*create_handle)(struct drm_framebuffer *fb,
|
||||
struct drm_file *file_priv,
|
||||
unsigned int *handle);
|
||||
};
|
||||
|
||||
struct drm_framebuffer {
|
||||
struct drm_device *dev;
|
||||
struct list_head head;
|
||||
struct drm_mode_object base;
|
||||
const struct drm_framebuffer_funcs *funcs;
|
||||
unsigned int pitch;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
/* depth can be 15 or 16 */
|
||||
unsigned int depth;
|
||||
int bits_per_pixel;
|
||||
int flags;
|
||||
void *fbdev;
|
||||
u32 pseudo_palette[17];
|
||||
struct list_head filp_head;
|
||||
};
|
||||
|
||||
struct drm_property_blob {
|
||||
struct drm_mode_object base;
|
||||
struct list_head head;
|
||||
unsigned int length;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct drm_property_enum {
|
||||
uint64_t value;
|
||||
struct list_head head;
|
||||
char name[DRM_PROP_NAME_LEN];
|
||||
};
|
||||
|
||||
struct drm_property {
|
||||
struct list_head head;
|
||||
struct drm_mode_object base;
|
||||
uint32_t flags;
|
||||
char name[DRM_PROP_NAME_LEN];
|
||||
uint32_t num_values;
|
||||
uint64_t *values;
|
||||
|
||||
struct list_head enum_blob_list;
|
||||
};
|
||||
|
||||
struct drm_crtc;
|
||||
struct drm_connector;
|
||||
struct drm_encoder;
|
||||
|
||||
/**
|
||||
* drm_crtc_funcs - control CRTCs for a given device
|
||||
* @dpms: control display power levels
|
||||
* @save: save CRTC state
|
||||
* @resore: restore CRTC state
|
||||
* @lock: lock the CRTC
|
||||
* @unlock: unlock the CRTC
|
||||
* @shadow_allocate: allocate shadow pixmap
|
||||
* @shadow_create: create shadow pixmap for rotation support
|
||||
* @shadow_destroy: free shadow pixmap
|
||||
* @mode_fixup: fixup proposed mode
|
||||
* @mode_set: set the desired mode on the CRTC
|
||||
* @gamma_set: specify color ramp for CRTC
|
||||
* @destroy: deinit and free object.
|
||||
*
|
||||
* The drm_crtc_funcs structure is the central CRTC management structure
|
||||
* in the DRM. Each CRTC controls one or more connectors (note that the name
|
||||
* CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc.
|
||||
* connectors, not just CRTs).
|
||||
*
|
||||
* Each driver is responsible for filling out this structure at startup time,
|
||||
* in addition to providing other modesetting features, like i2c and DDC
|
||||
* bus accessors.
|
||||
*/
|
||||
struct drm_crtc_funcs {
|
||||
/* Save CRTC state */
|
||||
void (*save)(struct drm_crtc *crtc); /* suspend? */
|
||||
/* Restore CRTC state */
|
||||
void (*restore)(struct drm_crtc *crtc); /* resume? */
|
||||
|
||||
/* cursor controls */
|
||||
int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,
|
||||
uint32_t handle, uint32_t width, uint32_t height);
|
||||
int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
|
||||
|
||||
/* Set gamma on the CRTC */
|
||||
void (*gamma_set)(struct drm_crtc *crtc, u16_t *r, u16_t *g, u16_t *b,
|
||||
uint32_t size);
|
||||
/* Object destroy routine */
|
||||
void (*destroy)(struct drm_crtc *crtc);
|
||||
|
||||
int (*set_config)(struct drm_mode_set *set);
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_crtc - central CRTC control structure
|
||||
* @enabled: is this CRTC enabled?
|
||||
* @x: x position on screen
|
||||
* @y: y position on screen
|
||||
* @desired_mode: new desired mode
|
||||
* @desired_x: desired x for desired_mode
|
||||
* @desired_y: desired y for desired_mode
|
||||
* @funcs: CRTC control functions
|
||||
*
|
||||
* Each CRTC may have one or more connectors associated with it. This structure
|
||||
* allows the CRTC to be controlled.
|
||||
*/
|
||||
struct drm_crtc {
|
||||
struct drm_device *dev;
|
||||
struct list_head head;
|
||||
|
||||
struct drm_mode_object base;
|
||||
|
||||
/* framebuffer the connector is currently bound to */
|
||||
struct drm_framebuffer *fb;
|
||||
|
||||
bool enabled;
|
||||
|
||||
struct drm_display_mode mode;
|
||||
|
||||
int x, y;
|
||||
struct drm_display_mode *desired_mode;
|
||||
int desired_x, desired_y;
|
||||
const struct drm_crtc_funcs *funcs;
|
||||
|
||||
/* CRTC gamma size for reporting to userspace */
|
||||
uint32_t gamma_size;
|
||||
uint16_t *gamma_store;
|
||||
|
||||
/* if you are using the helper */
|
||||
void *helper_private;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* drm_connector_funcs - control connectors on a given device
|
||||
* @dpms: set power state (see drm_crtc_funcs above)
|
||||
* @save: save connector state
|
||||
* @restore: restore connector state
|
||||
* @mode_valid: is this mode valid on the given connector?
|
||||
* @mode_fixup: try to fixup proposed mode for this connector
|
||||
* @mode_set: set this mode
|
||||
* @detect: is this connector active?
|
||||
* @get_modes: get mode list for this connector
|
||||
* @set_property: property for this connector may need update
|
||||
* @destroy: make object go away
|
||||
*
|
||||
* Each CRTC may have one or more connectors attached to it. The functions
|
||||
* below allow the core DRM code to control connectors, enumerate available modes,
|
||||
* etc.
|
||||
*/
|
||||
struct drm_connector_funcs {
|
||||
void (*dpms)(struct drm_connector *connector, int mode);
|
||||
void (*save)(struct drm_connector *connector);
|
||||
void (*restore)(struct drm_connector *connector);
|
||||
enum drm_connector_status (*detect)(struct drm_connector *connector);
|
||||
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
|
||||
int (*set_property)(struct drm_connector *connector, struct drm_property *property,
|
||||
uint64_t val);
|
||||
void (*destroy)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
struct drm_encoder_funcs {
|
||||
void (*destroy)(struct drm_encoder *encoder);
|
||||
};
|
||||
|
||||
#define DRM_CONNECTOR_MAX_UMODES 16
|
||||
#define DRM_CONNECTOR_MAX_PROPERTY 16
|
||||
#define DRM_CONNECTOR_LEN 32
|
||||
#define DRM_CONNECTOR_MAX_ENCODER 2
|
||||
|
||||
/**
|
||||
* drm_encoder - central DRM encoder structure
|
||||
*/
|
||||
struct drm_encoder {
|
||||
struct drm_device *dev;
|
||||
struct list_head head;
|
||||
|
||||
struct drm_mode_object base;
|
||||
int encoder_type;
|
||||
uint32_t possible_crtcs;
|
||||
uint32_t possible_clones;
|
||||
|
||||
struct drm_crtc *crtc;
|
||||
const struct drm_encoder_funcs *funcs;
|
||||
void *helper_private;
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_connector - central DRM connector control structure
|
||||
* @crtc: CRTC this connector is currently connected to, NULL if none
|
||||
* @interlace_allowed: can this connector handle interlaced modes?
|
||||
* @doublescan_allowed: can this connector handle doublescan?
|
||||
* @available_modes: modes available on this connector (from get_modes() + user)
|
||||
* @initial_x: initial x position for this connector
|
||||
* @initial_y: initial y position for this connector
|
||||
* @status: connector connected?
|
||||
* @funcs: connector control functions
|
||||
*
|
||||
* Each connector may be connected to one or more CRTCs, or may be clonable by
|
||||
* another connector if they can share a CRTC. Each connector also has a specific
|
||||
* position in the broader display (referred to as a 'screen' though it could
|
||||
* span multiple monitors).
|
||||
*/
|
||||
struct drm_connector {
|
||||
struct drm_device *dev;
|
||||
// struct device kdev;
|
||||
struct device_attribute *attr;
|
||||
struct list_head head;
|
||||
|
||||
struct drm_mode_object base;
|
||||
|
||||
int connector_type;
|
||||
int connector_type_id;
|
||||
bool interlace_allowed;
|
||||
bool doublescan_allowed;
|
||||
struct list_head modes; /* list of modes on this connector */
|
||||
|
||||
int initial_x, initial_y;
|
||||
enum drm_connector_status status;
|
||||
|
||||
/* these are modes added by probing with DDC or the BIOS */
|
||||
struct list_head probed_modes;
|
||||
|
||||
struct drm_display_info display_info;
|
||||
const struct drm_connector_funcs *funcs;
|
||||
|
||||
struct list_head user_modes;
|
||||
struct drm_property_blob *edid_blob_ptr;
|
||||
u32_t property_ids[DRM_CONNECTOR_MAX_PROPERTY];
|
||||
uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
|
||||
|
||||
/* requested DPMS state */
|
||||
int dpms;
|
||||
|
||||
void *helper_private;
|
||||
|
||||
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
|
||||
uint32_t force_encoder_id;
|
||||
struct drm_encoder *encoder; /* currently active encoder */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_mode_set
|
||||
*
|
||||
* Represents a single crtc the connectors that it drives with what mode
|
||||
* and from which framebuffer it scans out from.
|
||||
*
|
||||
* This is used to set modes.
|
||||
*/
|
||||
struct drm_mode_set {
|
||||
struct list_head head;
|
||||
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
|
||||
struct drm_connector **connectors;
|
||||
size_t num_connectors;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_mode_config_funcs - configure CRTCs for a given screen layout
|
||||
* @resize: adjust CRTCs as necessary for the proposed layout
|
||||
*
|
||||
* Currently only a resize hook is available. DRM will call back into the
|
||||
* driver with a new screen width and height. If the driver can't support
|
||||
* the proposed size, it can return false. Otherwise it should adjust
|
||||
* the CRTC<->connector mappings as needed and update its view of the screen.
|
||||
*/
|
||||
struct drm_mode_config_funcs {
|
||||
struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
|
||||
int (*fb_changed)(struct drm_device *dev);
|
||||
};
|
||||
|
||||
struct drm_mode_group {
|
||||
uint32_t num_crtcs;
|
||||
uint32_t num_encoders;
|
||||
uint32_t num_connectors;
|
||||
|
||||
/* list of object IDs for this group */
|
||||
uint32_t *id_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_mode_config - Mode configuration control structure
|
||||
*
|
||||
*/
|
||||
struct drm_mode_config {
|
||||
// struct mutex mutex; /* protects configuration (mode lists etc.) */
|
||||
// struct mutex idr_mutex; /* for IDR management */
|
||||
struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
|
||||
/* this is limited to one for now */
|
||||
int num_fb;
|
||||
struct list_head fb_list;
|
||||
int num_connector;
|
||||
struct list_head connector_list;
|
||||
int num_encoder;
|
||||
struct list_head encoder_list;
|
||||
|
||||
int num_crtc;
|
||||
struct list_head crtc_list;
|
||||
|
||||
struct list_head property_list;
|
||||
|
||||
/* in-kernel framebuffers - hung of filp_head in drm_framebuffer */
|
||||
struct list_head fb_kernel_list;
|
||||
|
||||
int min_width, min_height;
|
||||
int max_width, max_height;
|
||||
struct drm_mode_config_funcs *funcs;
|
||||
resource_size_t fb_base;
|
||||
|
||||
/* pointers to standard properties */
|
||||
struct list_head property_blob_list;
|
||||
struct drm_property *edid_property;
|
||||
struct drm_property *dpms_property;
|
||||
|
||||
/* DVI-I properties */
|
||||
struct drm_property *dvi_i_subconnector_property;
|
||||
struct drm_property *dvi_i_select_subconnector_property;
|
||||
|
||||
/* TV properties */
|
||||
struct drm_property *tv_subconnector_property;
|
||||
struct drm_property *tv_select_subconnector_property;
|
||||
struct drm_property *tv_mode_property;
|
||||
struct drm_property *tv_left_margin_property;
|
||||
struct drm_property *tv_right_margin_property;
|
||||
struct drm_property *tv_top_margin_property;
|
||||
struct drm_property *tv_bottom_margin_property;
|
||||
|
||||
/* Optional properties */
|
||||
struct drm_property *scaling_mode_property;
|
||||
struct drm_property *dithering_mode_property;
|
||||
};
|
||||
|
||||
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
|
||||
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
|
||||
#define obj_to_encoder(x) container_of(x, struct drm_encoder, base)
|
||||
#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
|
||||
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
|
||||
#define obj_to_property(x) container_of(x, struct drm_property, base)
|
||||
#define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
|
||||
|
||||
extern void drm_crtc_init(struct drm_device *dev,
|
||||
struct drm_crtc *crtc,
|
||||
const struct drm_crtc_funcs *funcs);
|
||||
extern void drm_crtc_cleanup(struct drm_crtc *crtc);
|
||||
|
||||
extern void drm_connector_init(struct drm_device *dev,
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector_funcs *funcs,
|
||||
int connector_type);
|
||||
|
||||
extern void drm_connector_cleanup(struct drm_connector *connector);
|
||||
|
||||
extern void drm_encoder_init(struct drm_device *dev,
|
||||
struct drm_encoder *encoder,
|
||||
const struct drm_encoder_funcs *funcs,
|
||||
int encoder_type);
|
||||
|
||||
extern void drm_encoder_cleanup(struct drm_encoder *encoder);
|
||||
|
||||
extern char *drm_get_connector_name(struct drm_connector *connector);
|
||||
extern char *drm_get_dpms_name(int val);
|
||||
extern char *drm_get_dvi_i_subconnector_name(int val);
|
||||
extern char *drm_get_dvi_i_select_name(int val);
|
||||
extern char *drm_get_tv_subconnector_name(int val);
|
||||
extern char *drm_get_tv_select_name(int val);
|
||||
|
||||
|
||||
|
||||
//extern void drm_fb_release(struct drm_file *file_priv);
|
||||
//extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
|
||||
//extern struct edid *drm_get_edid(struct drm_connector *connector,
|
||||
// struct i2c_adapter *adapter);
|
||||
//extern int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
|
||||
// unsigned char *buf, int len);
|
||||
//extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
|
||||
extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
|
||||
extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode);
|
||||
extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
|
||||
struct drm_display_mode *mode);
|
||||
extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
|
||||
extern void drm_mode_config_init(struct drm_device *dev);
|
||||
extern void drm_mode_config_cleanup(struct drm_device *dev);
|
||||
extern void drm_mode_set_name(struct drm_display_mode *mode);
|
||||
extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
|
||||
extern int drm_mode_width(struct drm_display_mode *mode);
|
||||
extern int drm_mode_height(struct drm_display_mode *mode);
|
||||
|
||||
/* for us by fb module */
|
||||
extern int drm_mode_attachmode_crtc(struct drm_device *dev,
|
||||
struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode);
|
||||
extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode);
|
||||
|
||||
extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
|
||||
extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
|
||||
//extern void drm_mode_list_concat(struct list_head *head,
|
||||
// struct list_head *new);
|
||||
//extern void drm_mode_validate_size(struct drm_device *dev,
|
||||
// struct list_head *mode_list,
|
||||
// int maxX, int maxY, int maxPitch);
|
||||
//extern void drm_mode_prune_invalid(struct drm_device *dev,
|
||||
// struct list_head *mode_list, bool verbose);
|
||||
//extern void drm_mode_sort(struct list_head *mode_list);
|
||||
extern int drm_mode_vrefresh(struct drm_display_mode *mode);
|
||||
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
|
||||
int adjust_flags);
|
||||
extern void drm_mode_connector_list_update(struct drm_connector *connector);
|
||||
//extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
||||
// struct edid *edid);
|
||||
extern int drm_connector_property_set_value(struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t value);
|
||||
extern int drm_connector_property_get_value(struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t *value);
|
||||
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
|
||||
extern void drm_framebuffer_set_object(struct drm_device *dev,
|
||||
unsigned long handle);
|
||||
extern int drm_framebuffer_init(struct drm_device *dev,
|
||||
struct drm_framebuffer *fb,
|
||||
const struct drm_framebuffer_funcs *funcs);
|
||||
extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
|
||||
extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
|
||||
extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
|
||||
extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY);
|
||||
extern bool drm_crtc_in_use(struct drm_crtc *crtc);
|
||||
|
||||
extern int drm_connector_attach_property(struct drm_connector *connector,
|
||||
struct drm_property *property, uint64_t init_val);
|
||||
extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
|
||||
const char *name, int num_values);
|
||||
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
|
||||
extern int drm_property_add_enum(struct drm_property *property, int index,
|
||||
uint64_t value, const char *name);
|
||||
extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
|
||||
extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats,
|
||||
char *formats[]);
|
||||
extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
|
||||
extern int drm_mode_create_dithering_property(struct drm_device *dev);
|
||||
extern char *drm_get_encoder_name(struct drm_encoder *encoder);
|
||||
|
||||
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
||||
struct drm_encoder *encoder);
|
||||
extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
|
||||
struct drm_encoder *encoder);
|
||||
extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
|
||||
int gamma_size);
|
||||
extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
|
||||
/* IOCTLs */
|
||||
extern int drm_mode_getresources(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
|
||||
extern int drm_mode_getcrtc(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_getconnector(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_setcrtc(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_cursor_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_addfb(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_rmfb(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_getfb(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_addmode_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_attachmode_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_detachmode_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
|
||||
extern int drm_mode_getproperty_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_getblob_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_replacefb(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_getencoder(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
//extern bool drm_detect_hdmi_monitor(struct edid *edid);
|
||||
|
||||
|
||||
#endif /* __DRM_CRTC_H__ */
|
||||
126
drivers/video/drm/include/drm_crtc_helper.h
Normal file
126
drivers/video/drm/include/drm_crtc_helper.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright © 2007-2008 Dave Airlie
|
||||
* Copyright © 2007-2008 Intel Corporation
|
||||
* Jesse Barnes <jesse.barnes@intel.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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The DRM mode setting helper functions are common code for drivers to use if
|
||||
* they wish. Drivers are not forced to use this code in their
|
||||
* implementations but it would be useful if they code they do use at least
|
||||
* provides a consistent interface and operation to userspace
|
||||
*/
|
||||
|
||||
#ifndef __DRM_CRTC_HELPER_H__
|
||||
#define __DRM_CRTC_HELPER_H__
|
||||
|
||||
//#include <linux/spinlock.h>
|
||||
//#include <linux/types.h>
|
||||
//#include <linux/idr.h>
|
||||
|
||||
//#include <linux/fb.h>
|
||||
|
||||
struct drm_crtc_helper_funcs {
|
||||
/*
|
||||
* Control power levels on the CRTC. If the mode passed in is
|
||||
* unsupported, the provider must use the next lowest power level.
|
||||
*/
|
||||
void (*dpms)(struct drm_crtc *crtc, int mode);
|
||||
void (*prepare)(struct drm_crtc *crtc);
|
||||
void (*commit)(struct drm_crtc *crtc);
|
||||
|
||||
/* Provider can fixup or change mode timings before modeset occurs */
|
||||
bool (*mode_fixup)(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
/* Actually set the mode */
|
||||
int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode, int x, int y,
|
||||
struct drm_framebuffer *old_fb);
|
||||
|
||||
/* Move the crtc on the current fb to the given position *optional* */
|
||||
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
|
||||
struct drm_framebuffer *old_fb);
|
||||
};
|
||||
|
||||
struct drm_encoder_helper_funcs {
|
||||
void (*dpms)(struct drm_encoder *encoder, int mode);
|
||||
void (*save)(struct drm_encoder *encoder);
|
||||
void (*restore)(struct drm_encoder *encoder);
|
||||
|
||||
bool (*mode_fixup)(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
void (*prepare)(struct drm_encoder *encoder);
|
||||
void (*commit)(struct drm_encoder *encoder);
|
||||
void (*mode_set)(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder);
|
||||
/* detect for DAC style encoders */
|
||||
enum drm_connector_status (*detect)(struct drm_encoder *encoder,
|
||||
struct drm_connector *connector);
|
||||
};
|
||||
|
||||
struct drm_connector_helper_funcs {
|
||||
int (*get_modes)(struct drm_connector *connector);
|
||||
int (*mode_valid)(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode);
|
||||
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
|
||||
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
|
||||
extern int drm_helper_hotplug_stage_two(struct drm_device *dev);
|
||||
extern bool drm_helper_initial_config(struct drm_device *dev);
|
||||
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
|
||||
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
int x, int y,
|
||||
struct drm_framebuffer *old_fb);
|
||||
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
|
||||
|
||||
extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
|
||||
|
||||
extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
|
||||
struct drm_mode_fb_cmd *mode_cmd);
|
||||
|
||||
static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
|
||||
const struct drm_crtc_helper_funcs *funcs)
|
||||
{
|
||||
crtc->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
static inline void drm_encoder_helper_add(struct drm_encoder *encoder,
|
||||
const struct drm_encoder_helper_funcs *funcs)
|
||||
{
|
||||
encoder->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
static inline void drm_connector_helper_add(struct drm_connector *connector,
|
||||
const struct drm_connector_helper_funcs *funcs)
|
||||
{
|
||||
connector->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
extern int drm_helper_resume_force_mode(struct drm_device *dev);
|
||||
#endif
|
||||
198
drivers/video/drm/include/drm_edid.h
Normal file
198
drivers/video/drm/include/drm_edid.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright © 2007-2008 Intel Corporation
|
||||
* Jesse Barnes <jesse.barnes@intel.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.
|
||||
*/
|
||||
#ifndef __DRM_EDID_H__
|
||||
#define __DRM_EDID_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define EDID_LENGTH 128
|
||||
#define DDC_ADDR 0x50
|
||||
|
||||
struct est_timings {
|
||||
u8 t1;
|
||||
u8 t2;
|
||||
u8 mfg_rsvd;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */
|
||||
#define EDID_TIMING_ASPECT_SHIFT 6
|
||||
#define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT)
|
||||
|
||||
/* need to add 60 */
|
||||
#define EDID_TIMING_VFREQ_SHIFT 0
|
||||
#define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT)
|
||||
|
||||
struct std_timing {
|
||||
u8 hsize; /* need to multiply by 8 then add 248 */
|
||||
u8 vfreq_aspect;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
|
||||
#define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
|
||||
#define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
|
||||
#define DRM_EDID_PT_STEREO (1 << 5)
|
||||
#define DRM_EDID_PT_INTERLACED (1 << 7)
|
||||
|
||||
/* If detailed data is pixel timing */
|
||||
struct detailed_pixel_timing {
|
||||
u8 hactive_lo;
|
||||
u8 hblank_lo;
|
||||
u8 hactive_hblank_hi;
|
||||
u8 vactive_lo;
|
||||
u8 vblank_lo;
|
||||
u8 vactive_vblank_hi;
|
||||
u8 hsync_offset_lo;
|
||||
u8 hsync_pulse_width_lo;
|
||||
u8 vsync_offset_pulse_width_lo;
|
||||
u8 hsync_vsync_offset_pulse_width_hi;
|
||||
u8 width_mm_lo;
|
||||
u8 height_mm_lo;
|
||||
u8 width_height_mm_hi;
|
||||
u8 hborder;
|
||||
u8 vborder;
|
||||
u8 misc;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* If it's not pixel timing, it'll be one of the below */
|
||||
struct detailed_data_string {
|
||||
u8 str[13];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct detailed_data_monitor_range {
|
||||
u8 min_vfreq;
|
||||
u8 max_vfreq;
|
||||
u8 min_hfreq_khz;
|
||||
u8 max_hfreq_khz;
|
||||
u8 pixel_clock_mhz; /* need to multiply by 10 */
|
||||
u16 sec_gtf_toggle; /* A000=use above, 20=use below */
|
||||
u8 hfreq_start_khz; /* need to multiply by 2 */
|
||||
u8 c; /* need to divide by 2 */
|
||||
u16 m;
|
||||
u8 k;
|
||||
u8 j; /* need to divide by 2 */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct detailed_data_wpindex {
|
||||
u8 white_yx_lo; /* Lower 2 bits each */
|
||||
u8 white_x_hi;
|
||||
u8 white_y_hi;
|
||||
u8 gamma; /* need to divide by 100 then add 1 */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct detailed_data_color_point {
|
||||
u8 windex1;
|
||||
u8 wpindex1[3];
|
||||
u8 windex2;
|
||||
u8 wpindex2[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct detailed_non_pixel {
|
||||
u8 pad1;
|
||||
u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
|
||||
fb=color point data, fa=standard timing data,
|
||||
f9=undefined, f8=mfg. reserved */
|
||||
u8 pad2;
|
||||
union {
|
||||
struct detailed_data_string str;
|
||||
struct detailed_data_monitor_range range;
|
||||
struct detailed_data_wpindex color;
|
||||
struct std_timing timings[5];
|
||||
} data;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define EDID_DETAIL_STD_MODES 0xfa
|
||||
#define EDID_DETAIL_MONITOR_CPDATA 0xfb
|
||||
#define EDID_DETAIL_MONITOR_NAME 0xfc
|
||||
#define EDID_DETAIL_MONITOR_RANGE 0xfd
|
||||
#define EDID_DETAIL_MONITOR_STRING 0xfe
|
||||
#define EDID_DETAIL_MONITOR_SERIAL 0xff
|
||||
|
||||
struct detailed_timing {
|
||||
u16 pixel_clock; /* need to multiply by 10 KHz */
|
||||
union {
|
||||
struct detailed_pixel_timing pixel_data;
|
||||
struct detailed_non_pixel other_data;
|
||||
} data;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0)
|
||||
#define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 1)
|
||||
#define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 2)
|
||||
#define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3)
|
||||
#define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4)
|
||||
#define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5)
|
||||
#define DRM_EDID_INPUT_DIGITAL (1 << 7) /* bits below must be zero if set */
|
||||
|
||||
#define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0)
|
||||
#define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1)
|
||||
#define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2)
|
||||
#define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */
|
||||
#define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 5)
|
||||
#define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6)
|
||||
#define DRM_EDID_FEATURE_PM_STANDBY (1 << 7)
|
||||
|
||||
struct edid {
|
||||
u8 header[8];
|
||||
/* Vendor & product info */
|
||||
u8 mfg_id[2];
|
||||
u8 prod_code[2];
|
||||
u32 serial; /* FIXME: byte order */
|
||||
u8 mfg_week;
|
||||
u8 mfg_year;
|
||||
/* EDID version */
|
||||
u8 version;
|
||||
u8 revision;
|
||||
/* Display info: */
|
||||
u8 input;
|
||||
u8 width_cm;
|
||||
u8 height_cm;
|
||||
u8 gamma;
|
||||
u8 features;
|
||||
/* Color characteristics */
|
||||
u8 red_green_lo;
|
||||
u8 black_white_lo;
|
||||
u8 red_x;
|
||||
u8 red_y;
|
||||
u8 green_x;
|
||||
u8 green_y;
|
||||
u8 blue_x;
|
||||
u8 blue_y;
|
||||
u8 white_x;
|
||||
u8 white_y;
|
||||
/* Est. timings and mfg rsvd timings*/
|
||||
struct est_timings established_timings;
|
||||
/* Standard timings 1-8*/
|
||||
struct std_timing standard_timings[8];
|
||||
/* Detailing timings 1-4 */
|
||||
struct detailed_timing detailed_timings[4];
|
||||
/* Number of 128 byte ext. blocks */
|
||||
u8 extensions;
|
||||
/* Checksum */
|
||||
u8 checksum;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
|
||||
|
||||
|
||||
|
||||
#endif /* __DRM_EDID_H__ */
|
||||
105
drivers/video/drm/include/drm_mm.h
Normal file
105
drivers/video/drm/include/drm_mm.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 (including the
|
||||
* next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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:
|
||||
* Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
#ifndef _DRM_MM_H_
|
||||
#define _DRM_MM_H_
|
||||
|
||||
/*
|
||||
* Generic range manager structs
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <list.h>
|
||||
#include <errno-base.h>
|
||||
|
||||
#define spin_lock_init(x)
|
||||
#define spin_lock(x)
|
||||
#define spin_unlock(x)
|
||||
|
||||
struct drm_mm_node {
|
||||
struct list_head fl_entry;
|
||||
struct list_head ml_entry;
|
||||
int free;
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
struct drm_mm *mm;
|
||||
void *private;
|
||||
};
|
||||
|
||||
struct drm_mm {
|
||||
struct list_head fl_entry;
|
||||
struct list_head ml_entry;
|
||||
struct list_head unused_nodes;
|
||||
int num_unused;
|
||||
// spinlock_t unused_lock;
|
||||
};
|
||||
|
||||
/*
|
||||
* Basic range manager support (drm_mm.c)
|
||||
*/
|
||||
extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
int atomic);
|
||||
static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
|
||||
unsigned long size,
|
||||
unsigned alignment)
|
||||
{
|
||||
return drm_mm_get_block_generic(parent, size, alignment, 0);
|
||||
}
|
||||
static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
|
||||
unsigned long size,
|
||||
unsigned alignment)
|
||||
{
|
||||
return drm_mm_get_block_generic(parent, size, alignment, 1);
|
||||
}
|
||||
extern void drm_mm_put_block(struct drm_mm_node *cur);
|
||||
extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
int best_match);
|
||||
extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
|
||||
unsigned long size);
|
||||
extern void drm_mm_takedown(struct drm_mm *mm);
|
||||
extern int drm_mm_clean(struct drm_mm *mm);
|
||||
extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
|
||||
extern int drm_mm_remove_space_from_tail(struct drm_mm *mm,
|
||||
unsigned long size);
|
||||
extern int drm_mm_add_space_to_tail(struct drm_mm *mm,
|
||||
unsigned long size, int atomic);
|
||||
extern int drm_mm_pre_get(struct drm_mm *mm);
|
||||
|
||||
static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
|
||||
{
|
||||
return block->mm;
|
||||
}
|
||||
|
||||
#endif
|
||||
268
drivers/video/drm/include/drm_mode.h
Normal file
268
drivers/video/drm/include/drm_mode.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
|
||||
* Copyright (c) 2007 Jakob Bornecrantz <wallbraker@gmail.com>
|
||||
* Copyright (c) 2008 Red Hat Inc.
|
||||
* Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
|
||||
* Copyright (c) 2007-2008 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*/
|
||||
|
||||
#ifndef _DRM_MODE_H
|
||||
#define _DRM_MODE_H
|
||||
|
||||
//#include <linux/kernel.h>
|
||||
//#include <linux/types.h>
|
||||
|
||||
#define DRM_DISPLAY_INFO_LEN 32
|
||||
#define DRM_CONNECTOR_NAME_LEN 32
|
||||
#define DRM_DISPLAY_MODE_LEN 32
|
||||
#define DRM_PROP_NAME_LEN 32
|
||||
|
||||
#define DRM_MODE_TYPE_BUILTIN (1<<0)
|
||||
#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
|
||||
#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
|
||||
#define DRM_MODE_TYPE_PREFERRED (1<<3)
|
||||
#define DRM_MODE_TYPE_DEFAULT (1<<4)
|
||||
#define DRM_MODE_TYPE_USERDEF (1<<5)
|
||||
#define DRM_MODE_TYPE_DRIVER (1<<6)
|
||||
|
||||
/* Video mode flags */
|
||||
/* bit compatible with the xorg definitions. */
|
||||
#define DRM_MODE_FLAG_PHSYNC (1<<0)
|
||||
#define DRM_MODE_FLAG_NHSYNC (1<<1)
|
||||
#define DRM_MODE_FLAG_PVSYNC (1<<2)
|
||||
#define DRM_MODE_FLAG_NVSYNC (1<<3)
|
||||
#define DRM_MODE_FLAG_INTERLACE (1<<4)
|
||||
#define DRM_MODE_FLAG_DBLSCAN (1<<5)
|
||||
#define DRM_MODE_FLAG_CSYNC (1<<6)
|
||||
#define DRM_MODE_FLAG_PCSYNC (1<<7)
|
||||
#define DRM_MODE_FLAG_NCSYNC (1<<8)
|
||||
#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
|
||||
#define DRM_MODE_FLAG_BCAST (1<<10)
|
||||
#define DRM_MODE_FLAG_PIXMUX (1<<11)
|
||||
#define DRM_MODE_FLAG_DBLCLK (1<<12)
|
||||
#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
|
||||
|
||||
/* DPMS flags */
|
||||
/* bit compatible with the xorg definitions. */
|
||||
#define DRM_MODE_DPMS_ON 0
|
||||
#define DRM_MODE_DPMS_STANDBY 1
|
||||
#define DRM_MODE_DPMS_SUSPEND 2
|
||||
#define DRM_MODE_DPMS_OFF 3
|
||||
|
||||
/* Scaling mode options */
|
||||
#define DRM_MODE_SCALE_NON_GPU 0
|
||||
#define DRM_MODE_SCALE_FULLSCREEN 1
|
||||
#define DRM_MODE_SCALE_NO_SCALE 2
|
||||
#define DRM_MODE_SCALE_ASPECT 3
|
||||
|
||||
/* Dithering mode options */
|
||||
#define DRM_MODE_DITHERING_OFF 0
|
||||
#define DRM_MODE_DITHERING_ON 1
|
||||
|
||||
struct drm_mode_modeinfo {
|
||||
__u32 clock;
|
||||
__u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
|
||||
__u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
|
||||
|
||||
__u32 vrefresh; /* vertical refresh * 1000 */
|
||||
|
||||
__u32 flags;
|
||||
__u32 type;
|
||||
char name[DRM_DISPLAY_MODE_LEN];
|
||||
};
|
||||
|
||||
struct drm_mode_card_res {
|
||||
__u64 fb_id_ptr;
|
||||
__u64 crtc_id_ptr;
|
||||
__u64 connector_id_ptr;
|
||||
__u64 encoder_id_ptr;
|
||||
__u32 count_fbs;
|
||||
__u32 count_crtcs;
|
||||
__u32 count_connectors;
|
||||
__u32 count_encoders;
|
||||
__u32 min_width, max_width;
|
||||
__u32 min_height, max_height;
|
||||
};
|
||||
|
||||
struct drm_mode_crtc {
|
||||
__u64 set_connectors_ptr;
|
||||
__u32 count_connectors;
|
||||
|
||||
__u32 crtc_id; /**< Id */
|
||||
__u32 fb_id; /**< Id of framebuffer */
|
||||
|
||||
__u32 x, y; /**< Position on the frameuffer */
|
||||
|
||||
__u32 gamma_size;
|
||||
__u32 mode_valid;
|
||||
struct drm_mode_modeinfo mode;
|
||||
};
|
||||
|
||||
#define DRM_MODE_ENCODER_NONE 0
|
||||
#define DRM_MODE_ENCODER_DAC 1
|
||||
#define DRM_MODE_ENCODER_TMDS 2
|
||||
#define DRM_MODE_ENCODER_LVDS 3
|
||||
#define DRM_MODE_ENCODER_TVDAC 4
|
||||
|
||||
struct drm_mode_get_encoder {
|
||||
__u32 encoder_id;
|
||||
__u32 encoder_type;
|
||||
|
||||
__u32 crtc_id; /**< Id of crtc */
|
||||
|
||||
__u32 possible_crtcs;
|
||||
__u32 possible_clones;
|
||||
};
|
||||
|
||||
/* This is for connectors with multiple signal types. */
|
||||
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
|
||||
#define DRM_MODE_SUBCONNECTOR_Automatic 0
|
||||
#define DRM_MODE_SUBCONNECTOR_Unknown 0
|
||||
#define DRM_MODE_SUBCONNECTOR_DVID 3
|
||||
#define DRM_MODE_SUBCONNECTOR_DVIA 4
|
||||
#define DRM_MODE_SUBCONNECTOR_Composite 5
|
||||
#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
|
||||
#define DRM_MODE_SUBCONNECTOR_Component 8
|
||||
|
||||
#define DRM_MODE_CONNECTOR_Unknown 0
|
||||
#define DRM_MODE_CONNECTOR_VGA 1
|
||||
#define DRM_MODE_CONNECTOR_DVII 2
|
||||
#define DRM_MODE_CONNECTOR_DVID 3
|
||||
#define DRM_MODE_CONNECTOR_DVIA 4
|
||||
#define DRM_MODE_CONNECTOR_Composite 5
|
||||
#define DRM_MODE_CONNECTOR_SVIDEO 6
|
||||
#define DRM_MODE_CONNECTOR_LVDS 7
|
||||
#define DRM_MODE_CONNECTOR_Component 8
|
||||
#define DRM_MODE_CONNECTOR_9PinDIN 9
|
||||
#define DRM_MODE_CONNECTOR_DisplayPort 10
|
||||
#define DRM_MODE_CONNECTOR_HDMIA 11
|
||||
#define DRM_MODE_CONNECTOR_HDMIB 12
|
||||
|
||||
struct drm_mode_get_connector {
|
||||
|
||||
__u64 encoders_ptr;
|
||||
__u64 modes_ptr;
|
||||
__u64 props_ptr;
|
||||
__u64 prop_values_ptr;
|
||||
|
||||
__u32 count_modes;
|
||||
__u32 count_props;
|
||||
__u32 count_encoders;
|
||||
|
||||
__u32 encoder_id; /**< Current Encoder */
|
||||
__u32 connector_id; /**< Id */
|
||||
__u32 connector_type;
|
||||
__u32 connector_type_id;
|
||||
|
||||
__u32 connection;
|
||||
__u32 mm_width, mm_height; /**< HxW in millimeters */
|
||||
__u32 subpixel;
|
||||
};
|
||||
|
||||
#define DRM_MODE_PROP_PENDING (1<<0)
|
||||
#define DRM_MODE_PROP_RANGE (1<<1)
|
||||
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
|
||||
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
|
||||
#define DRM_MODE_PROP_BLOB (1<<4)
|
||||
|
||||
struct drm_mode_property_enum {
|
||||
__u64 value;
|
||||
char name[DRM_PROP_NAME_LEN];
|
||||
};
|
||||
|
||||
struct drm_mode_get_property {
|
||||
__u64 values_ptr; /* values and blob lengths */
|
||||
__u64 enum_blob_ptr; /* enum and blob id ptrs */
|
||||
|
||||
__u32 prop_id;
|
||||
__u32 flags;
|
||||
char name[DRM_PROP_NAME_LEN];
|
||||
|
||||
__u32 count_values;
|
||||
__u32 count_enum_blobs;
|
||||
};
|
||||
|
||||
struct drm_mode_connector_set_property {
|
||||
__u64 value;
|
||||
__u32 prop_id;
|
||||
__u32 connector_id;
|
||||
};
|
||||
|
||||
struct drm_mode_get_blob {
|
||||
__u32 blob_id;
|
||||
__u32 length;
|
||||
__u64 data;
|
||||
};
|
||||
|
||||
struct drm_mode_fb_cmd {
|
||||
__u32 fb_id;
|
||||
__u32 width, height;
|
||||
__u32 pitch;
|
||||
__u32 bpp;
|
||||
__u32 depth;
|
||||
/* driver specific handle */
|
||||
__u32 handle;
|
||||
};
|
||||
|
||||
struct drm_mode_mode_cmd {
|
||||
__u32 connector_id;
|
||||
struct drm_mode_modeinfo mode;
|
||||
};
|
||||
|
||||
#define DRM_MODE_CURSOR_BO (1<<0)
|
||||
#define DRM_MODE_CURSOR_MOVE (1<<1)
|
||||
|
||||
/*
|
||||
* depending on the value in flags diffrent members are used.
|
||||
*
|
||||
* CURSOR_BO uses
|
||||
* crtc
|
||||
* width
|
||||
* height
|
||||
* handle - if 0 turns the cursor of
|
||||
*
|
||||
* CURSOR_MOVE uses
|
||||
* crtc
|
||||
* x
|
||||
* y
|
||||
*/
|
||||
struct drm_mode_cursor {
|
||||
__u32 flags;
|
||||
__u32 crtc_id;
|
||||
__s32 x;
|
||||
__s32 y;
|
||||
__u32 width;
|
||||
__u32 height;
|
||||
/* driver specific handle */
|
||||
__u32 handle;
|
||||
};
|
||||
|
||||
struct drm_mode_crtc_lut {
|
||||
__u32 crtc_id;
|
||||
__u32 gamma_size;
|
||||
|
||||
/* pointers to arrays */
|
||||
__u64 red;
|
||||
__u64 green;
|
||||
__u64 blue;
|
||||
};
|
||||
|
||||
#endif
|
||||
39
drivers/video/drm/include/errno-base.h
Normal file
39
drivers/video/drm/include/errno-base.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef _ASM_GENERIC_ERRNO_BASE_H
|
||||
#define _ASM_GENERIC_ERRNO_BASE_H
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Argument list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EAGAIN 11 /* Try again */
|
||||
#define ENOMEM 12 /* Out of memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* File table overflow */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math argument out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
|
||||
#endif
|
||||
111
drivers/video/drm/include/errno.h
Normal file
111
drivers/video/drm/include/errno.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef _ASM_GENERIC_ERRNO_H
|
||||
#define _ASM_GENERIC_ERRNO_H
|
||||
|
||||
#include <errno-base.h>
|
||||
|
||||
#define EDEADLK 35 /* Resource deadlock would occur */
|
||||
#define ENAMETOOLONG 36 /* File name too long */
|
||||
#define ENOLCK 37 /* No record locks available */
|
||||
#define ENOSYS 38 /* Function not implemented */
|
||||
#define ENOTEMPTY 39 /* Directory not empty */
|
||||
#define ELOOP 40 /* Too many symbolic links encountered */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
#define ENOMSG 42 /* No message of desired type */
|
||||
#define EIDRM 43 /* Identifier removed */
|
||||
#define ECHRNG 44 /* Channel number out of range */
|
||||
#define EL2NSYNC 45 /* Level 2 not synchronized */
|
||||
#define EL3HLT 46 /* Level 3 halted */
|
||||
#define EL3RST 47 /* Level 3 reset */
|
||||
#define ELNRNG 48 /* Link number out of range */
|
||||
#define EUNATCH 49 /* Protocol driver not attached */
|
||||
#define ENOCSI 50 /* No CSI structure available */
|
||||
#define EL2HLT 51 /* Level 2 halted */
|
||||
#define EBADE 52 /* Invalid exchange */
|
||||
#define EBADR 53 /* Invalid request descriptor */
|
||||
#define EXFULL 54 /* Exchange full */
|
||||
#define ENOANO 55 /* No anode */
|
||||
#define EBADRQC 56 /* Invalid request code */
|
||||
#define EBADSLT 57 /* Invalid slot */
|
||||
|
||||
#define EDEADLOCK EDEADLK
|
||||
|
||||
#define EBFONT 59 /* Bad font file format */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data available */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* Object is remote */
|
||||
#define ENOLINK 67 /* Link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 72 /* Multihop attempted */
|
||||
#define EDOTDOT 73 /* RFS specific error */
|
||||
#define EBADMSG 74 /* Not a data message */
|
||||
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||
#define ENOTUNIQ 76 /* Name not unique on network */
|
||||
#define EBADFD 77 /* File descriptor in bad state */
|
||||
#define EREMCHG 78 /* Remote address changed */
|
||||
#define ELIBACC 79 /* Can not access a needed shared library */
|
||||
#define ELIBBAD 80 /* Accessing a corrupted shared library */
|
||||
#define ELIBSCN 81 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
|
||||
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
|
||||
#define EILSEQ 84 /* Illegal byte sequence */
|
||||
#define ERESTART 85 /* Interrupted system call should be restarted */
|
||||
#define ESTRPIPE 86 /* Streams pipe error */
|
||||
#define EUSERS 87 /* Too many users */
|
||||
#define ENOTSOCK 88 /* Socket operation on non-socket */
|
||||
#define EDESTADDRREQ 89 /* Destination address required */
|
||||
#define EMSGSIZE 90 /* Message too long */
|
||||
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
|
||||
#define ENOPROTOOPT 92 /* Protocol not available */
|
||||
#define EPROTONOSUPPORT 93 /* Protocol not supported */
|
||||
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||
#define EADDRINUSE 98 /* Address already in use */
|
||||
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
|
||||
#define ENETDOWN 100 /* Network is down */
|
||||
#define ENETUNREACH 101 /* Network is unreachable */
|
||||
#define ENETRESET 102 /* Network dropped connection because of reset */
|
||||
#define ECONNABORTED 103 /* Software caused connection abort */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EISCONN 106 /* Transport endpoint is already connected */
|
||||
#define ENOTCONN 107 /* Transport endpoint is not connected */
|
||||
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
|
||||
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
|
||||
#define ETIMEDOUT 110 /* Connection timed out */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EHOSTDOWN 112 /* Host is down */
|
||||
#define EHOSTUNREACH 113 /* No route to host */
|
||||
#define EALREADY 114 /* Operation already in progress */
|
||||
#define EINPROGRESS 115 /* Operation now in progress */
|
||||
#define ESTALE 116 /* Stale NFS file handle */
|
||||
#define EUCLEAN 117 /* Structure needs cleaning */
|
||||
#define ENOTNAM 118 /* Not a XENIX named type file */
|
||||
#define ENAVAIL 119 /* No XENIX semaphores available */
|
||||
#define EISNAM 120 /* Is a named type file */
|
||||
#define EREMOTEIO 121 /* Remote I/O error */
|
||||
#define EDQUOT 122 /* Quota exceeded */
|
||||
|
||||
#define ENOMEDIUM 123 /* No medium found */
|
||||
#define EMEDIUMTYPE 124 /* Wrong medium type */
|
||||
#define ECANCELED 125 /* Operation Canceled */
|
||||
#define ENOKEY 126 /* Required key not available */
|
||||
#define EKEYEXPIRED 127 /* Key has expired */
|
||||
#define EKEYREVOKED 128 /* Key has been revoked */
|
||||
#define EKEYREJECTED 129 /* Key was rejected by service */
|
||||
|
||||
/* for robust mutexes */
|
||||
#define EOWNERDEAD 130 /* Owner died */
|
||||
#define ENOTRECOVERABLE 131 /* State not recoverable */
|
||||
|
||||
#define ERFKILL 132 /* Operation not possible due to RF-kill */
|
||||
|
||||
#endif
|
||||
191
drivers/video/drm/include/linux/bitops.h
Normal file
191
drivers/video/drm/include/linux/bitops.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#define _LINUX_BITOPS_H
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
#define BITS_PER_BYTE 8
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
||||
|
||||
/*
|
||||
* Include this here because some architectures need generic_ffs/fls in
|
||||
* scope
|
||||
*/
|
||||
#include <asm/bitops.h>
|
||||
|
||||
#define for_each_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
|
||||
static __inline__ int get_bitmask_order(unsigned int count)
|
||||
{
|
||||
int order;
|
||||
|
||||
order = fls(count);
|
||||
return order; /* We could be slightly more clever with -1 here... */
|
||||
}
|
||||
|
||||
static __inline__ int get_count_order(unsigned int count)
|
||||
{
|
||||
int order;
|
||||
|
||||
order = fls(count) - 1;
|
||||
if (count & (count - 1))
|
||||
order++;
|
||||
return order;
|
||||
}
|
||||
|
||||
static inline unsigned long hweight_long(unsigned long w)
|
||||
{
|
||||
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
|
||||
}
|
||||
|
||||
/**
|
||||
* rol32 - rotate a 32-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u32 rol32(__u32 word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (32 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror32 - rotate a 32-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u32 ror32(__u32 word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (32 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol16 - rotate a 16-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u16 rol16(__u16 word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (16 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror16 - rotate a 16-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u16 ror16(__u16 word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (16 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol8 - rotate an 8-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u8 rol8(__u8 word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (8 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror8 - rotate an 8-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline __u8 ror8(__u8 word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (8 - shift));
|
||||
}
|
||||
|
||||
static inline unsigned fls_long(unsigned long l)
|
||||
{
|
||||
if (sizeof(l) == 4)
|
||||
return fls(l);
|
||||
return fls64(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* __ffs64 - find first set bit in a 64 bit word
|
||||
* @word: The 64 bit word
|
||||
*
|
||||
* On 64 bit arches this is a synomyn for __ffs
|
||||
* The result is not defined if no bits are set, so check that @word
|
||||
* is non-zero before calling this.
|
||||
*/
|
||||
static inline unsigned long __ffs64(u64 word)
|
||||
{
|
||||
#if BITS_PER_LONG == 32
|
||||
if (((u32)word) == 0UL)
|
||||
return __ffs((u32)(word >> 32)) + 32;
|
||||
#elif BITS_PER_LONG != 64
|
||||
#error BITS_PER_LONG not 32 or 64
|
||||
#endif
|
||||
return __ffs((unsigned long)word);
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_GENERIC_FIND_FIRST_BIT
|
||||
|
||||
/**
|
||||
* find_first_bit - find the first set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum size to search
|
||||
*
|
||||
* Returns the bit number of the first set bit.
|
||||
*/
|
||||
extern unsigned long find_first_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
|
||||
/**
|
||||
* find_first_zero_bit - find the first cleared bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum size to search
|
||||
*
|
||||
* Returns the bit number of the first cleared bit.
|
||||
*/
|
||||
extern unsigned long find_first_zero_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
|
||||
|
||||
#ifdef CONFIG_GENERIC_FIND_LAST_BIT
|
||||
/**
|
||||
* find_last_bit - find the last set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum size to search
|
||||
*
|
||||
* Returns the bit number of the first set bit, or size.
|
||||
*/
|
||||
extern unsigned long find_last_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
#endif /* CONFIG_GENERIC_FIND_LAST_BIT */
|
||||
|
||||
#ifdef CONFIG_GENERIC_FIND_NEXT_BIT
|
||||
|
||||
/**
|
||||
* find_next_bit - find the next set bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*/
|
||||
extern unsigned long find_next_bit(const unsigned long *addr,
|
||||
unsigned long size, unsigned long offset);
|
||||
|
||||
/**
|
||||
* find_next_zero_bit - find the next cleared bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*/
|
||||
|
||||
extern unsigned long find_next_zero_bit(const unsigned long *addr,
|
||||
unsigned long size,
|
||||
unsigned long offset);
|
||||
|
||||
#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
51
drivers/video/drm/include/linux/i2c-algo-bit.h
Normal file
51
drivers/video/drm/include/linux/i2c-algo-bit.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* i2c-algo-bit.h i2c driver algorithms for bit-shift adapters */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Copyright (C) 1995-99 Simon G. Vogl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
|
||||
Frodo Looijaard <frodol@dds.nl> */
|
||||
|
||||
#ifndef _LINUX_I2C_ALGO_BIT_H
|
||||
#define _LINUX_I2C_ALGO_BIT_H
|
||||
|
||||
/* --- Defines for bit-adapters --------------------------------------- */
|
||||
/*
|
||||
* This struct contains the hw-dependent functions of bit-style adapters to
|
||||
* manipulate the line states, and to init any hw-specific features. This is
|
||||
* only used if you have more than one hw-type of adapter running.
|
||||
*/
|
||||
struct i2c_algo_bit_data {
|
||||
void *data; /* private data for lowlevel routines */
|
||||
void (*setsda) (void *data, int state);
|
||||
void (*setscl) (void *data, int state);
|
||||
int (*getsda) (void *data);
|
||||
int (*getscl) (void *data);
|
||||
|
||||
/* local settings */
|
||||
int udelay; /* half clock cycle time in us,
|
||||
minimum 2 us for fast-mode I2C,
|
||||
minimum 5 us for standard-mode I2C and SMBus,
|
||||
maximum 50 us for SMBus */
|
||||
int timeout; /* in jiffies */
|
||||
};
|
||||
|
||||
int i2c_bit_add_bus(struct i2c_adapter *);
|
||||
int i2c_bit_add_numbered_bus(struct i2c_adapter *);
|
||||
|
||||
#endif /* _LINUX_I2C_ALGO_BIT_H */
|
||||
299
drivers/video/drm/include/linux/i2c.h
Normal file
299
drivers/video/drm/include/linux/i2c.h
Normal file
@@ -0,0 +1,299 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* */
|
||||
/* i2c.h - definitions for the i2c-bus interface */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Copyright (C) 1995-2000 Simon G. Vogl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
|
||||
Frodo Looijaard <frodol@dds.nl> */
|
||||
|
||||
#ifndef _LINUX_I2C_H
|
||||
#define _LINUX_I2C_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
|
||||
|
||||
#define I2C_NAME_SIZE 20
|
||||
|
||||
struct i2c_msg;
|
||||
struct i2c_algorithm;
|
||||
struct i2c_adapter;
|
||||
struct i2c_client;
|
||||
union i2c_smbus_data;
|
||||
|
||||
|
||||
/* Transfer num messages.
|
||||
*/
|
||||
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num);
|
||||
|
||||
/**
|
||||
* struct i2c_client - represent an I2C slave device
|
||||
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
|
||||
* I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
|
||||
* @addr: Address used on the I2C bus connected to the parent adapter.
|
||||
* @name: Indicates the type of the device, usually a chip name that's
|
||||
* generic enough to hide second-sourcing and compatible revisions.
|
||||
* @adapter: manages the bus segment hosting this I2C device
|
||||
* @driver: device's driver, hence pointer to access routines
|
||||
* @dev: Driver model device node for the slave.
|
||||
* @irq: indicates the IRQ generated by this device (if any)
|
||||
* @detected: member of an i2c_driver.clients list or i2c-core's
|
||||
* userspace_devices list
|
||||
*
|
||||
* An i2c_client identifies a single device (i.e. chip) connected to an
|
||||
* i2c bus. The behaviour exposed to Linux is defined by the driver
|
||||
* managing the device.
|
||||
*/
|
||||
struct i2c_client {
|
||||
unsigned short flags; /* div., see below */
|
||||
unsigned short addr; /* chip address - NOTE: 7bit */
|
||||
/* addresses are stored in the */
|
||||
/* _LOWER_ 7 bits */
|
||||
char name[I2C_NAME_SIZE];
|
||||
struct i2c_adapter *adapter; /* the adapter we sit on */
|
||||
// struct i2c_driver *driver; /* and our access routines */
|
||||
// struct device dev; /* the device structure */
|
||||
int irq; /* irq issued by device (or -1) */
|
||||
struct list_head detected;
|
||||
};
|
||||
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
|
||||
|
||||
|
||||
/*
|
||||
* The following structs are for those who like to implement new bus drivers:
|
||||
* i2c_algorithm is the interface to a class of hardware solutions which can
|
||||
* be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
|
||||
* to name two of the most common.
|
||||
*/
|
||||
struct i2c_algorithm {
|
||||
/* If an adapter algorithm can't do I2C-level access, set master_xfer
|
||||
to NULL. If an adapter algorithm can do SMBus access, set
|
||||
smbus_xfer. If set to NULL, the SMBus protocol is simulated
|
||||
using common I2C messages */
|
||||
/* master_xfer should return the number of messages successfully
|
||||
processed, or a negative value on error */
|
||||
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
int num);
|
||||
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
|
||||
unsigned short flags, char read_write,
|
||||
u8 command, int size, union i2c_smbus_data *data);
|
||||
|
||||
/* To determine what the adapter supports */
|
||||
u32 (*functionality) (struct i2c_adapter *);
|
||||
};
|
||||
|
||||
/*
|
||||
* i2c_adapter is the structure used to identify a physical i2c bus along
|
||||
* with the access algorithms necessary to access it.
|
||||
*/
|
||||
struct i2c_adapter {
|
||||
unsigned int id;
|
||||
unsigned int class; /* classes to allow probing for */
|
||||
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
|
||||
void *algo_data;
|
||||
|
||||
/* data fields that are valid for all devices */
|
||||
u8 level; /* nesting level for lockdep */
|
||||
|
||||
int timeout; /* in jiffies */
|
||||
int retries;
|
||||
// struct device dev; /* the adapter device */
|
||||
|
||||
int nr;
|
||||
char name[48];
|
||||
};
|
||||
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
|
||||
|
||||
|
||||
/*flags for the client struct: */
|
||||
#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
|
||||
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
|
||||
/* Must equal I2C_M_TEN below */
|
||||
#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */
|
||||
|
||||
/* i2c adapter classes (bitmask) */
|
||||
#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */
|
||||
#define I2C_CLASS_TV_ANALOG (1<<1) /* bttv + friends */
|
||||
#define I2C_CLASS_TV_DIGITAL (1<<2) /* dvb cards */
|
||||
#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */
|
||||
#define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */
|
||||
|
||||
/* i2c_client_address_data is the struct for holding default client
|
||||
* addresses for a driver and for the parameters supplied on the
|
||||
* command line
|
||||
*/
|
||||
struct i2c_client_address_data {
|
||||
const unsigned short *normal_i2c;
|
||||
const unsigned short *probe;
|
||||
const unsigned short *ignore;
|
||||
const unsigned short * const *forces;
|
||||
};
|
||||
|
||||
/* Internal numbers to terminate lists */
|
||||
#define I2C_CLIENT_END 0xfffeU
|
||||
|
||||
/* The numbers to use to set I2C bus address */
|
||||
#define ANY_I2C_BUS 0xffff
|
||||
|
||||
/* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
|
||||
#define I2C_ADDRS(addr, addrs...) \
|
||||
((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
|
||||
|
||||
|
||||
/**
|
||||
* struct i2c_msg - an I2C transaction segment beginning with START
|
||||
* @addr: Slave address, either seven or ten bits. When this is a ten
|
||||
* bit address, I2C_M_TEN must be set in @flags and the adapter
|
||||
* must support I2C_FUNC_10BIT_ADDR.
|
||||
* @flags: I2C_M_RD is handled by all adapters. No other flags may be
|
||||
* provided unless the adapter exported the relevant I2C_FUNC_*
|
||||
* flags through i2c_check_functionality().
|
||||
* @len: Number of data bytes in @buf being read from or written to the
|
||||
* I2C slave address. For read transactions where I2C_M_RECV_LEN
|
||||
* is set, the caller guarantees that this buffer can hold up to
|
||||
* 32 bytes in addition to the initial length byte sent by the
|
||||
* slave (plus, if used, the SMBus PEC); and this value will be
|
||||
* incremented by the number of block data bytes received.
|
||||
* @buf: The buffer into which data is read, or from which it's written.
|
||||
*
|
||||
* An i2c_msg is the low level representation of one segment of an I2C
|
||||
* transaction. It is visible to drivers in the @i2c_transfer() procedure,
|
||||
* to userspace from i2c-dev, and to I2C adapter drivers through the
|
||||
* @i2c_adapter.@master_xfer() method.
|
||||
*
|
||||
* Except when I2C "protocol mangling" is used, all I2C adapters implement
|
||||
* the standard rules for I2C transactions. Each transaction begins with a
|
||||
* START. That is followed by the slave address, and a bit encoding read
|
||||
* versus write. Then follow all the data bytes, possibly including a byte
|
||||
* with SMBus PEC. The transfer terminates with a NAK, or when all those
|
||||
* bytes have been transferred and ACKed. If this is the last message in a
|
||||
* group, it is followed by a STOP. Otherwise it is followed by the next
|
||||
* @i2c_msg transaction segment, beginning with a (repeated) START.
|
||||
*
|
||||
* Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
|
||||
* passing certain @flags may have changed those standard protocol behaviors.
|
||||
* Those flags are only for use with broken/nonconforming slaves, and with
|
||||
* adapters which are known to support the specific mangling options they
|
||||
* need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
|
||||
*/
|
||||
struct i2c_msg {
|
||||
u16 addr; /* slave address */
|
||||
u16 flags;
|
||||
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
|
||||
#define I2C_M_RD 0x0001 /* read data, from slave to master */
|
||||
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
|
||||
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
|
||||
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
|
||||
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
|
||||
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
|
||||
u16 len; /* msg length */
|
||||
u8 *buf; /* pointer to msg data */
|
||||
};
|
||||
|
||||
/* To determine what functionality is present */
|
||||
|
||||
#define I2C_FUNC_I2C 0x00000001
|
||||
#define I2C_FUNC_10BIT_ADDR 0x00000002
|
||||
#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */
|
||||
#define I2C_FUNC_SMBUS_PEC 0x00000008
|
||||
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
|
||||
#define I2C_FUNC_SMBUS_QUICK 0x00010000
|
||||
#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
|
||||
#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
|
||||
#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
|
||||
#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
|
||||
#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
|
||||
#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
|
||||
#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
|
||||
#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
|
||||
#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
|
||||
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
|
||||
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
|
||||
|
||||
#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
|
||||
I2C_FUNC_SMBUS_WRITE_BYTE)
|
||||
#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
|
||||
I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
|
||||
#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
|
||||
I2C_FUNC_SMBUS_WRITE_WORD_DATA)
|
||||
#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
|
||||
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
|
||||
#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
|
||||
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
|
||||
|
||||
#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
|
||||
I2C_FUNC_SMBUS_BYTE | \
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | \
|
||||
I2C_FUNC_SMBUS_WORD_DATA | \
|
||||
I2C_FUNC_SMBUS_PROC_CALL | \
|
||||
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
|
||||
I2C_FUNC_SMBUS_I2C_BLOCK | \
|
||||
I2C_FUNC_SMBUS_PEC)
|
||||
|
||||
/*
|
||||
* Data for SMBus Messages
|
||||
*/
|
||||
#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
|
||||
union i2c_smbus_data {
|
||||
__u8 byte;
|
||||
__u16 word;
|
||||
__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
|
||||
/* and one more for user-space compatibility */
|
||||
};
|
||||
|
||||
/* i2c_smbus_xfer read or write markers */
|
||||
#define I2C_SMBUS_READ 1
|
||||
#define I2C_SMBUS_WRITE 0
|
||||
|
||||
/* SMBus transaction types (size parameter in the above functions)
|
||||
Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
|
||||
#define I2C_SMBUS_QUICK 0
|
||||
#define I2C_SMBUS_BYTE 1
|
||||
#define I2C_SMBUS_BYTE_DATA 2
|
||||
#define I2C_SMBUS_WORD_DATA 3
|
||||
#define I2C_SMBUS_PROC_CALL 4
|
||||
#define I2C_SMBUS_BLOCK_DATA 5
|
||||
#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
|
||||
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
|
||||
#define I2C_SMBUS_I2C_BLOCK_DATA 8
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _LINUX_I2C_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
144
drivers/video/drm/include/linux/idr.h
Normal file
144
drivers/video/drm/include/linux/idr.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* include/linux/idr.h
|
||||
*
|
||||
* 2002-10-18 written by Jim Houston jim.houston@ccur.com
|
||||
* Copyright (C) 2002 by Concurrent Computer Corporation
|
||||
* Distributed under the GNU GPL license version 2.
|
||||
*
|
||||
* Small id to pointer translation service avoiding fixed sized
|
||||
* tables.
|
||||
*/
|
||||
|
||||
#ifndef __IDR_H__
|
||||
#define __IDR_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <errno-base.h>
|
||||
|
||||
//#include <linux/bitops.h>
|
||||
//#include <linux/init.h>
|
||||
//#include <linux/rcupdate.h>
|
||||
|
||||
struct rcu_head {
|
||||
struct rcu_head *next;
|
||||
void (*func)(struct rcu_head *head);
|
||||
};
|
||||
|
||||
|
||||
# define IDR_BITS 5
|
||||
# define IDR_FULL 0xfffffffful
|
||||
/* We can only use two of the bits in the top level because there is
|
||||
only one possible bit in the top level (5 bits * 7 levels = 35
|
||||
bits, but you only use 31 bits in the id). */
|
||||
# define TOP_LEVEL_FULL (IDR_FULL >> 30)
|
||||
|
||||
#define IDR_SIZE (1 << IDR_BITS)
|
||||
#define IDR_MASK ((1 << IDR_BITS)-1)
|
||||
|
||||
#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
|
||||
#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
|
||||
#define MAX_ID_MASK (MAX_ID_BIT - 1)
|
||||
|
||||
/* Leave the possibility of an incomplete final layer */
|
||||
#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
|
||||
|
||||
/* Number of id_layer structs to leave in free list */
|
||||
#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
|
||||
|
||||
struct idr_layer {
|
||||
unsigned long bitmap; /* A zero bit means "space here" */
|
||||
struct idr_layer *ary[1<<IDR_BITS];
|
||||
int count; /* When zero, we can release it */
|
||||
int layer; /* distance from leaf */
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
|
||||
struct idr {
|
||||
struct idr_layer *top;
|
||||
struct idr_layer *id_free;
|
||||
int layers; /* only valid without concurrent changes */
|
||||
int id_free_cnt;
|
||||
// spinlock_t lock;
|
||||
};
|
||||
|
||||
#define IDR_INIT(name) \
|
||||
{ \
|
||||
.top = NULL, \
|
||||
.id_free = NULL, \
|
||||
.layers = 0, \
|
||||
.id_free_cnt = 0, \
|
||||
// .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
|
||||
}
|
||||
#define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
|
||||
|
||||
/* Actions to be taken after a call to _idr_sub_alloc */
|
||||
#define IDR_NEED_TO_GROW -2
|
||||
#define IDR_NOMORE_SPACE -3
|
||||
|
||||
#define _idr_rc_to_errno(rc) ((rc) == -1 ? -EAGAIN : -ENOSPC)
|
||||
|
||||
/**
|
||||
* idr synchronization (stolen from radix-tree.h)
|
||||
*
|
||||
* idr_find() is able to be called locklessly, using RCU. The caller must
|
||||
* ensure calls to this function are made within rcu_read_lock() regions.
|
||||
* Other readers (lock-free or otherwise) and modifications may be running
|
||||
* concurrently.
|
||||
*
|
||||
* It is still required that the caller manage the synchronization and
|
||||
* lifetimes of the items. So if RCU lock-free lookups are used, typically
|
||||
* this would mean that the items have their own locks, or are amenable to
|
||||
* lock-free access; and that the items are freed by RCU (or only freed after
|
||||
* having been deleted from the idr tree *and* a synchronize_rcu() grace
|
||||
* period).
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is what we export.
|
||||
*/
|
||||
|
||||
void *idr_find(struct idr *idp, int id);
|
||||
int idr_pre_get(struct idr *idp, u32_t gfp_mask);
|
||||
int idr_get_new(struct idr *idp, void *ptr, int *id);
|
||||
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
|
||||
int idr_for_each(struct idr *idp,
|
||||
int (*fn)(int id, void *p, void *data), void *data);
|
||||
void *idr_get_next(struct idr *idp, int *nextid);
|
||||
void *idr_replace(struct idr *idp, void *ptr, int id);
|
||||
void idr_remove(struct idr *idp, int id);
|
||||
void idr_remove_all(struct idr *idp);
|
||||
void idr_destroy(struct idr *idp);
|
||||
void idr_init(struct idr *idp);
|
||||
|
||||
|
||||
/*
|
||||
* IDA - IDR based id allocator, use when translation from id to
|
||||
* pointer isn't necessary.
|
||||
*/
|
||||
#define IDA_CHUNK_SIZE 128 /* 128 bytes per chunk */
|
||||
#define IDA_BITMAP_LONGS (128 / sizeof(long) - 1)
|
||||
#define IDA_BITMAP_BITS (IDA_BITMAP_LONGS * sizeof(long) * 8)
|
||||
|
||||
struct ida_bitmap {
|
||||
long nr_busy;
|
||||
unsigned long bitmap[IDA_BITMAP_LONGS];
|
||||
};
|
||||
|
||||
struct ida {
|
||||
struct idr idr;
|
||||
struct ida_bitmap *free_bitmap;
|
||||
};
|
||||
|
||||
#define IDA_INIT(name) { .idr = IDR_INIT(name), .free_bitmap = NULL, }
|
||||
#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
|
||||
|
||||
int ida_pre_get(struct ida *ida, u32_t gfp_mask);
|
||||
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
|
||||
int ida_get_new(struct ida *ida, int *p_id);
|
||||
void ida_remove(struct ida *ida, int id);
|
||||
void ida_destroy(struct ida *ida);
|
||||
void ida_init(struct ida *ida);
|
||||
|
||||
void idr_init_cache(void);
|
||||
|
||||
#endif /* __IDR_H__ */
|
||||
703
drivers/video/drm/include/list.h
Normal file
703
drivers/video/drm/include/list.h
Normal file
@@ -0,0 +1,703 @@
|
||||
#ifndef _LINUX_LIST_H
|
||||
#define _LINUX_LIST_H
|
||||
|
||||
//#include <linux/stddef.h>
|
||||
//#include <linux/poison.h>
|
||||
//#include <linux/prefetch.h>
|
||||
//#include <asm/system.h>
|
||||
|
||||
/*
|
||||
* Simple doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole lists rather than single entries, as
|
||||
* sometimes we already know the next/prev entries and we can
|
||||
* generate better code by using them directly rather than
|
||||
* using the generic single-entry routines.
|
||||
*/
|
||||
|
||||
#define LIST_POISON1 ((struct list_head*)0xFFFF0100)
|
||||
#define LIST_POISON2 ((struct list_head*)0xFFFF0200)
|
||||
|
||||
#define prefetch(x) __builtin_prefetch(x)
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
#else
|
||||
extern void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a list entry by making the prev/next entries
|
||||
* point to each other.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_del(struct list_head * prev, struct list_head * next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del - deletes entry from list.
|
||||
* @entry: the element to delete from the list.
|
||||
* Note: list_empty() on entry does not return true after this, the entry is
|
||||
* in an undefined state.
|
||||
*/
|
||||
#ifndef CONFIG_DEBUG_LIST
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->next = LIST_POISON1;
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
#else
|
||||
extern void list_del(struct list_head *entry);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* list_replace - replace old entry by new one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
*
|
||||
* If @old was empty, it will be overwritten.
|
||||
*/
|
||||
static inline void list_replace(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
new->prev = old->prev;
|
||||
new->prev->next = new;
|
||||
}
|
||||
|
||||
static inline void list_replace_init(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
list_replace(old, new);
|
||||
INIT_LIST_HEAD(old);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_init - deletes entry from list and reinitialize it.
|
||||
* @entry: the element to delete from the list.
|
||||
*/
|
||||
static inline void list_del_init(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
INIT_LIST_HEAD(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move - delete from one list and add as another's head
|
||||
* @list: the entry to move
|
||||
* @head: the head that will precede our entry
|
||||
*/
|
||||
static inline void list_move(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
__list_del(list->prev, list->next);
|
||||
list_add(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move_tail - delete from one list and add as another's tail
|
||||
* @list: the entry to move
|
||||
* @head: the head that will follow our entry
|
||||
*/
|
||||
static inline void list_move_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
__list_del(list->prev, list->next);
|
||||
list_add_tail(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_last - tests whether @list is the last entry in list @head
|
||||
* @list: the entry to test
|
||||
* @head: the head of the list
|
||||
*/
|
||||
static inline int list_is_last(const struct list_head *list,
|
||||
const struct list_head *head)
|
||||
{
|
||||
return list->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty - tests whether a list is empty
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static inline int list_empty(const struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty_careful - tests whether a list is empty and not being modified
|
||||
* @head: the list to test
|
||||
*
|
||||
* Description:
|
||||
* tests whether a list is empty _and_ checks that no other CPU might be
|
||||
* in the process of modifying either member (next or prev)
|
||||
*
|
||||
* NOTE: using list_empty_careful() without synchronization
|
||||
* can only be safe if the only activity that can happen
|
||||
* to the list entry is list_del_init(). Eg. it cannot be used
|
||||
* if another CPU could re-list_add() it.
|
||||
*/
|
||||
static inline int list_empty_careful(const struct list_head *head)
|
||||
{
|
||||
struct list_head *next = head->next;
|
||||
return (next == head) && (next == head->prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_is_singular - tests whether a list has just one entry.
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static inline int list_is_singular(const struct list_head *head)
|
||||
{
|
||||
return !list_empty(head) && (head->next == head->prev);
|
||||
}
|
||||
|
||||
static inline void __list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
struct list_head *new_first = entry->next;
|
||||
list->next = head->next;
|
||||
list->next->prev = list;
|
||||
list->prev = entry;
|
||||
entry->next = list;
|
||||
head->next = new_first;
|
||||
new_first->prev = head;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_cut_position - cut a list into two
|
||||
* @list: a new list to add all removed entries
|
||||
* @head: a list with entries
|
||||
* @entry: an entry within head, could be the head itself
|
||||
* and if so we won't cut the list
|
||||
*
|
||||
* This helper moves the initial part of @head, up to and
|
||||
* including @entry, from @head to @list. You should
|
||||
* pass on @entry an element you know is on @head. @list
|
||||
* should be an empty list or a list you do not care about
|
||||
* losing its data.
|
||||
*
|
||||
*/
|
||||
static inline void list_cut_position(struct list_head *list,
|
||||
struct list_head *head, struct list_head *entry)
|
||||
{
|
||||
if (list_empty(head))
|
||||
return;
|
||||
if (list_is_singular(head) &&
|
||||
(head->next != entry && head != entry))
|
||||
return;
|
||||
if (entry == head)
|
||||
INIT_LIST_HEAD(list);
|
||||
else
|
||||
__list_cut_position(list, head, entry);
|
||||
}
|
||||
|
||||
static inline void __list_splice(const struct list_head *list,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
struct list_head *last = list->prev;
|
||||
|
||||
first->prev = prev;
|
||||
prev->next = first;
|
||||
|
||||
last->next = next;
|
||||
next->prev = last;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice - join two lists, this is designed for stacks
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice(const struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_tail - join two lists, each list being a queue
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head->prev, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_init - join two lists and reinitialise the emptied list.
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* The list at @list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head, head->next);
|
||||
INIT_LIST_HEAD(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_tail_init - join two lists and reinitialise the emptied list
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* Each of the lists is a queue.
|
||||
* The list at @list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_tail_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head->prev, head);
|
||||
INIT_LIST_HEAD(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_entry - get the struct for this entry
|
||||
* @ptr: the &struct list_head pointer.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
/**
|
||||
* list_first_entry - get the first element from a list
|
||||
* @ptr: the list head to take the element from.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Note, that list is expected to be not empty.
|
||||
*/
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
/**
|
||||
* list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* __list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*
|
||||
* This variant differs from list_for_each() in that it's the
|
||||
* simplest possible list iteration code, no prefetching is done.
|
||||
* Use this for code that knows the list to be very short (empty
|
||||
* or 1 entry) most of the time.
|
||||
*/
|
||||
#define __list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev - iterate over a list backwards
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev(pos, head) \
|
||||
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
|
||||
pos = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_safe - iterate over a list safe against removal of list entry
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @n: another &struct list_head to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @n: another &struct list_head to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev_safe(pos, n, head) \
|
||||
for (pos = (head)->prev, n = pos->prev; \
|
||||
prefetch(pos->prev), pos != (head); \
|
||||
pos = n, n = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_entry - iterate over list of given type
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_reverse - iterate backwards over list of given type.
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_reverse(pos, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
|
||||
* @pos: the type * to use as a start point
|
||||
* @head: the head of the list
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
|
||||
*/
|
||||
#define list_prepare_entry(pos, head, member) \
|
||||
((pos) ? : list_entry(head, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue - continue iteration over list of given type
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Continue to iterate over list of given type, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_continue_reverse - iterate backwards from the given point
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Start to iterate over list of given type backwards, continuing after
|
||||
* the current position.
|
||||
*/
|
||||
#define list_for_each_entry_continue_reverse(pos, head, member) \
|
||||
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
prefetch(pos->member.prev), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_from - iterate over list of given type from the current point
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing from current position.
|
||||
*/
|
||||
#define list_for_each_entry_from(pos, head, member) \
|
||||
for (; prefetch(pos->member.next), &pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_continue
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type, continuing after current point,
|
||||
* safe against removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_continue(pos, n, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_from
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate over list of given type from current point, safe against
|
||||
* removal of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_from(pos, n, head, member) \
|
||||
for (n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_reverse
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* Iterate backwards over list of given type, safe against removal
|
||||
* of list entry.
|
||||
*/
|
||||
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->prev, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.prev, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
|
||||
|
||||
/*
|
||||
* Double linked lists with a single pointer list head.
|
||||
* Mostly useful for hash tables where the two pointer list head is
|
||||
* too wasteful.
|
||||
* You lose the ability to access the tail in O(1).
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
|
||||
#define HLIST_HEAD_INIT { .first = NULL }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||
{
|
||||
h->next = NULL;
|
||||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
}
|
||||
|
||||
static inline void __hlist_del(struct hlist_node *n)
|
||||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = LIST_POISON1;
|
||||
n->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
__hlist_del(n);
|
||||
INIT_HLIST_NODE(n);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
/* next must be != NULL */
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
|
||||
if(next->next)
|
||||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move a list from one list head to another. Fixup the pprev
|
||||
* reference of the first entry if it exists.
|
||||
*/
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
new->first->pprev = &new->first;
|
||||
old->first = NULL;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry - iterate over list of given type
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @n: another &struct hlist_node to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = n)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
566
drivers/video/drm/include/pci.h
Normal file
566
drivers/video/drm/include/pci.h
Normal file
@@ -0,0 +1,566 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifndef __PCI_H__
|
||||
#define __PCI_H__
|
||||
|
||||
#define PCI_ANY_ID (~0)
|
||||
|
||||
|
||||
#define PCI_CLASS_NOT_DEFINED 0x0000
|
||||
#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
|
||||
|
||||
#define PCI_BASE_CLASS_STORAGE 0x01
|
||||
#define PCI_CLASS_STORAGE_SCSI 0x0100
|
||||
#define PCI_CLASS_STORAGE_IDE 0x0101
|
||||
#define PCI_CLASS_STORAGE_FLOPPY 0x0102
|
||||
#define PCI_CLASS_STORAGE_IPI 0x0103
|
||||
#define PCI_CLASS_STORAGE_RAID 0x0104
|
||||
#define PCI_CLASS_STORAGE_SATA 0x0106
|
||||
#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601
|
||||
#define PCI_CLASS_STORAGE_SAS 0x0107
|
||||
#define PCI_CLASS_STORAGE_OTHER 0x0180
|
||||
|
||||
#define PCI_BASE_CLASS_NETWORK 0x02
|
||||
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
|
||||
#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
|
||||
#define PCI_CLASS_NETWORK_FDDI 0x0202
|
||||
#define PCI_CLASS_NETWORK_ATM 0x0203
|
||||
#define PCI_CLASS_NETWORK_OTHER 0x0280
|
||||
|
||||
#define PCI_BASE_CLASS_DISPLAY 0x03
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
#define PCI_CLASS_DISPLAY_XGA 0x0301
|
||||
#define PCI_CLASS_DISPLAY_3D 0x0302
|
||||
#define PCI_CLASS_DISPLAY_OTHER 0x0380
|
||||
|
||||
#define PCI_BASE_CLASS_MULTIMEDIA 0x04
|
||||
#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
|
||||
#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
|
||||
#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
|
||||
#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
|
||||
|
||||
#define PCI_BASE_CLASS_MEMORY 0x05
|
||||
#define PCI_CLASS_MEMORY_RAM 0x0500
|
||||
#define PCI_CLASS_MEMORY_FLASH 0x0501
|
||||
#define PCI_CLASS_MEMORY_OTHER 0x0580
|
||||
|
||||
#define PCI_BASE_CLASS_BRIDGE 0x06
|
||||
#define PCI_CLASS_BRIDGE_HOST 0x0600
|
||||
#define PCI_CLASS_BRIDGE_ISA 0x0601
|
||||
#define PCI_CLASS_BRIDGE_EISA 0x0602
|
||||
#define PCI_CLASS_BRIDGE_MC 0x0603
|
||||
#define PCI_CLASS_BRIDGE_PCI 0x0604
|
||||
#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
|
||||
#define PCI_CLASS_BRIDGE_NUBUS 0x0606
|
||||
#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
|
||||
#define PCI_CLASS_BRIDGE_RACEWAY 0x0608
|
||||
#define PCI_CLASS_BRIDGE_OTHER 0x0680
|
||||
|
||||
#define PCI_BASE_CLASS_COMMUNICATION 0x07
|
||||
#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
|
||||
#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
|
||||
#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
|
||||
#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
|
||||
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
|
||||
|
||||
#define PCI_BASE_CLASS_SYSTEM 0x08
|
||||
#define PCI_CLASS_SYSTEM_PIC 0x0800
|
||||
#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010
|
||||
#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020
|
||||
#define PCI_CLASS_SYSTEM_DMA 0x0801
|
||||
#define PCI_CLASS_SYSTEM_TIMER 0x0802
|
||||
#define PCI_CLASS_SYSTEM_RTC 0x0803
|
||||
#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
|
||||
#define PCI_CLASS_SYSTEM_SDHCI 0x0805
|
||||
#define PCI_CLASS_SYSTEM_OTHER 0x0880
|
||||
|
||||
#define PCI_BASE_CLASS_INPUT 0x09
|
||||
#define PCI_CLASS_INPUT_KEYBOARD 0x0900
|
||||
#define PCI_CLASS_INPUT_PEN 0x0901
|
||||
#define PCI_CLASS_INPUT_MOUSE 0x0902
|
||||
#define PCI_CLASS_INPUT_SCANNER 0x0903
|
||||
#define PCI_CLASS_INPUT_GAMEPORT 0x0904
|
||||
#define PCI_CLASS_INPUT_OTHER 0x0980
|
||||
|
||||
#define PCI_BASE_CLASS_DOCKING 0x0a
|
||||
#define PCI_CLASS_DOCKING_GENERIC 0x0a00
|
||||
#define PCI_CLASS_DOCKING_OTHER 0x0a80
|
||||
|
||||
#define PCI_BASE_CLASS_PROCESSOR 0x0b
|
||||
#define PCI_CLASS_PROCESSOR_386 0x0b00
|
||||
#define PCI_CLASS_PROCESSOR_486 0x0b01
|
||||
#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
|
||||
#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
|
||||
#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
|
||||
#define PCI_CLASS_PROCESSOR_MIPS 0x0b30
|
||||
#define PCI_CLASS_PROCESSOR_CO 0x0b40
|
||||
|
||||
#define PCI_BASE_CLASS_SERIAL 0x0c
|
||||
#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
|
||||
#define PCI_CLASS_SERIAL_FIREWIRE_OHCI 0x0c0010
|
||||
#define PCI_CLASS_SERIAL_ACCESS 0x0c01
|
||||
#define PCI_CLASS_SERIAL_SSA 0x0c02
|
||||
#define PCI_CLASS_SERIAL_USB 0x0c03
|
||||
#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300
|
||||
#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310
|
||||
#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320
|
||||
#define PCI_CLASS_SERIAL_FIBER 0x0c04
|
||||
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
|
||||
|
||||
#define PCI_BASE_CLASS_WIRELESS 0x0d
|
||||
#define PCI_CLASS_WIRELESS_RF_CONTROLLER 0x0d10
|
||||
#define PCI_CLASS_WIRELESS_WHCI 0x0d1010
|
||||
|
||||
#define PCI_BASE_CLASS_INTELLIGENT 0x0e
|
||||
#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
|
||||
|
||||
#define PCI_BASE_CLASS_SATELLITE 0x0f
|
||||
#define PCI_CLASS_SATELLITE_TV 0x0f00
|
||||
#define PCI_CLASS_SATELLITE_AUDIO 0x0f01
|
||||
#define PCI_CLASS_SATELLITE_VOICE 0x0f03
|
||||
#define PCI_CLASS_SATELLITE_DATA 0x0f04
|
||||
|
||||
#define PCI_BASE_CLASS_CRYPT 0x10
|
||||
#define PCI_CLASS_CRYPT_NETWORK 0x1000
|
||||
#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001
|
||||
#define PCI_CLASS_CRYPT_OTHER 0x1080
|
||||
|
||||
#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
|
||||
#define PCI_CLASS_SP_DPIO 0x1100
|
||||
#define PCI_CLASS_SP_OTHER 0x1180
|
||||
|
||||
#define PCI_CLASS_OTHERS 0xff
|
||||
|
||||
|
||||
/*
|
||||
* Under PCI, each device has 256 bytes of configuration address space,
|
||||
* of which the first 64 bytes are standardized as follows:
|
||||
*/
|
||||
#define PCI_VENDOR_ID 0x000 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x002 /* 16 bits */
|
||||
#define PCI_COMMAND 0x004 /* 16 bits */
|
||||
#define PCI_COMMAND_IO 0x001 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEMORY 0x002 /* Enable response in Memory space */
|
||||
#define PCI_COMMAND_MASTER 0x004 /* Enable bus mastering */
|
||||
#define PCI_COMMAND_SPECIAL 0x008 /* Enable response to special cycles */
|
||||
#define PCI_COMMAND_INVALIDATE 0x010 /* Use memory write and invalidate */
|
||||
#define PCI_COMMAND_VGA_PALETTE 0x020 /* Enable palette snooping */
|
||||
#define PCI_COMMAND_PARITY 0x040 /* Enable parity checking */
|
||||
#define PCI_COMMAND_WAIT 0x080 /* Enable address/data stepping */
|
||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
||||
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
|
||||
|
||||
#define PCI_STATUS 0x006 /* 16 bits */
|
||||
#define PCI_STATUS_CAP_LIST 0x010 /* Support Capability List */
|
||||
#define PCI_STATUS_66MHZ 0x020 /* Support 66 Mhz PCI 2.1 bus */
|
||||
#define PCI_STATUS_UDF 0x040 /* Support User Definable Features [obsolete] */
|
||||
#define PCI_STATUS_FAST_BACK 0x080 /* Accept fast-back to back */
|
||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
||||
|
||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
|
||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
#define PCI_HEADER_TYPE_NORMAL 0
|
||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||
|
||||
#define PCI_BIST 0x0f /* 8 bits */
|
||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
||||
|
||||
/*
|
||||
* Base addresses specify locations in memory or I/O space.
|
||||
* Decoded size can be determined by writing a value of
|
||||
* 0xffffffff to the register, and reading it back. Only
|
||||
* 1 bits are decoded.
|
||||
*/
|
||||
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
|
||||
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
|
||||
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
|
||||
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
|
||||
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
|
||||
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
|
||||
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
|
||||
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
|
||||
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
||||
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
|
||||
/* bit 1 is reserved if address_space = 1 */
|
||||
|
||||
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
|
||||
|
||||
/* Header type 0 (normal devices) */
|
||||
#define PCI_CARDBUS_CIS 0x28
|
||||
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
|
||||
#define PCI_SUBSYSTEM_ID 0x2e
|
||||
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
|
||||
#define PCI_ROM_ADDRESS_ENABLE 0x01
|
||||
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
|
||||
|
||||
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
|
||||
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
|
||||
|
||||
|
||||
#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
|
||||
#define PCI_CB_SUBSYSTEM_ID 0x42
|
||||
|
||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
||||
/* Capability lists */
|
||||
|
||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
|
||||
#define PCI_CAP_ID_HT 0x08 /* HyperTransport */
|
||||
#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */
|
||||
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
|
||||
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
|
||||
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
|
||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||
#define PCI_CAP_SIZEOF 4
|
||||
|
||||
|
||||
/* AGP registers */
|
||||
|
||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_AGP_STATUS 4 /* Status register */
|
||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
|
||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
|
||||
#define PCI_AGP_SIZEOF 12
|
||||
|
||||
|
||||
#define PCI_MAP_REG_START 0x10
|
||||
#define PCI_MAP_REG_END 0x28
|
||||
#define PCI_MAP_ROM_REG 0x30
|
||||
|
||||
#define PCI_MAP_MEMORY 0x00000000
|
||||
#define PCI_MAP_IO 0x00000001
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE 0x00000007
|
||||
#define PCI_MAP_IO_TYPE 0x00000003
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
|
||||
#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
|
||||
#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
|
||||
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
|
||||
#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ATTR_MASK 0x00000003
|
||||
|
||||
|
||||
|
||||
#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
|
||||
#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
|
||||
|
||||
#define PCI_MAP_IS64BITMEM(b) \
|
||||
(((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
|
||||
|
||||
#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
|
||||
#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1))
|
||||
#define PCIGETMEMORY64(b) \
|
||||
(PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32))
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
|
||||
#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
|
||||
|
||||
#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
|
||||
#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
|
||||
|
||||
#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
|
||||
|
||||
|
||||
#ifndef PCI_DOM_MASK
|
||||
# define PCI_DOM_MASK 0x0ffu
|
||||
#endif
|
||||
#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu)
|
||||
|
||||
#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \
|
||||
(((d) & 0x00001fu) << 11) | \
|
||||
(((f) & 0x000007u) << 8))
|
||||
|
||||
#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK))
|
||||
#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11)
|
||||
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
|
||||
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
|
||||
|
||||
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
|
||||
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
|
||||
|
||||
|
||||
typedef unsigned int PCITAG;
|
||||
|
||||
extern inline PCITAG
|
||||
pciTag(int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
|
||||
struct resource
|
||||
{
|
||||
resource_size_t start;
|
||||
resource_size_t end;
|
||||
// const char *name;
|
||||
unsigned long flags;
|
||||
// struct resource *parent, *sibling, *child;
|
||||
};
|
||||
|
||||
/*
|
||||
* IO resources have these defined flags.
|
||||
*/
|
||||
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
|
||||
|
||||
#define IORESOURCE_IO 0x00000100 /* Resource type */
|
||||
#define IORESOURCE_MEM 0x00000200
|
||||
#define IORESOURCE_IRQ 0x00000400
|
||||
#define IORESOURCE_DMA 0x00000800
|
||||
|
||||
#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
|
||||
#define IORESOURCE_READONLY 0x00002000
|
||||
#define IORESOURCE_CACHEABLE 0x00004000
|
||||
#define IORESOURCE_RANGELENGTH 0x00008000
|
||||
#define IORESOURCE_SHADOWABLE 0x00010000
|
||||
#define IORESOURCE_BUS_HAS_VGA 0x00080000
|
||||
|
||||
#define IORESOURCE_DISABLED 0x10000000
|
||||
#define IORESOURCE_UNSET 0x20000000
|
||||
#define IORESOURCE_AUTO 0x40000000
|
||||
#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
|
||||
|
||||
/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */
|
||||
#define IORESOURCE_IRQ_HIGHEDGE (1<<0)
|
||||
#define IORESOURCE_IRQ_LOWEDGE (1<<1)
|
||||
#define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
|
||||
#define IORESOURCE_IRQ_LOWLEVEL (1<<3)
|
||||
#define IORESOURCE_IRQ_SHAREABLE (1<<4)
|
||||
|
||||
/* ISA PnP DMA specific bits (IORESOURCE_BITS) */
|
||||
#define IORESOURCE_DMA_TYPE_MASK (3<<0)
|
||||
#define IORESOURCE_DMA_8BIT (0<<0)
|
||||
#define IORESOURCE_DMA_8AND16BIT (1<<0)
|
||||
#define IORESOURCE_DMA_16BIT (2<<0)
|
||||
|
||||
#define IORESOURCE_DMA_MASTER (1<<2)
|
||||
#define IORESOURCE_DMA_BYTE (1<<3)
|
||||
#define IORESOURCE_DMA_WORD (1<<4)
|
||||
|
||||
#define IORESOURCE_DMA_SPEED_MASK (3<<6)
|
||||
#define IORESOURCE_DMA_COMPATIBLE (0<<6)
|
||||
#define IORESOURCE_DMA_TYPEA (1<<6)
|
||||
#define IORESOURCE_DMA_TYPEB (2<<6)
|
||||
#define IORESOURCE_DMA_TYPEF (3<<6)
|
||||
|
||||
/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */
|
||||
#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */
|
||||
#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */
|
||||
#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */
|
||||
#define IORESOURCE_MEM_TYPE_MASK (3<<3)
|
||||
#define IORESOURCE_MEM_8BIT (0<<3)
|
||||
#define IORESOURCE_MEM_16BIT (1<<3)
|
||||
#define IORESOURCE_MEM_8AND16BIT (2<<3)
|
||||
#define IORESOURCE_MEM_32BIT (3<<3)
|
||||
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
|
||||
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
|
||||
|
||||
/* PCI ROM control bits (IORESOURCE_BITS) */
|
||||
#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
|
||||
#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
|
||||
#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
|
||||
#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */
|
||||
|
||||
/* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */
|
||||
#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */
|
||||
|
||||
|
||||
/*
|
||||
* For PCI devices, the region numbers are assigned this way:
|
||||
*
|
||||
* 0-5 standard PCI regions
|
||||
* 6 expansion ROM
|
||||
* 7-10 bridges: address space assigned to buses behind the bridge
|
||||
*/
|
||||
|
||||
#define PCI_ROM_RESOURCE 6
|
||||
#define PCI_BRIDGE_RESOURCES 7
|
||||
#define PCI_NUM_RESOURCES 11
|
||||
|
||||
#ifndef PCI_BUS_NUM_RESOURCES
|
||||
#define PCI_BUS_NUM_RESOURCES 8
|
||||
#endif
|
||||
|
||||
#define DEVICE_COUNT_RESOURCE 12
|
||||
|
||||
/*
|
||||
* The pci_dev structure is used to describe PCI devices.
|
||||
*/
|
||||
struct pci_dev {
|
||||
// struct list_head bus_list; /* node in per-bus list */
|
||||
// struct pci_bus *bus; /* bus this device is on */
|
||||
// struct pci_bus *subordinate; /* bus this device bridges to */
|
||||
|
||||
// void *sysdata; /* hook for sys-specific extension */
|
||||
// struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
|
||||
// struct pci_slot *slot; /* Physical slot this device is in */
|
||||
u32_t bus;
|
||||
u32_t devfn; /* encoded device & function index */
|
||||
u16_t vendor;
|
||||
u16_t device;
|
||||
u16_t subsystem_vendor;
|
||||
u16_t subsystem_device;
|
||||
u32_t class; /* 3 bytes: (base,sub,prog-if) */
|
||||
uint8_t revision; /* PCI revision, low byte of class word */
|
||||
uint8_t hdr_type; /* PCI header type (`multi' flag masked out) */
|
||||
uint8_t pcie_type; /* PCI-E device/port type */
|
||||
uint8_t rom_base_reg; /* which config register controls the ROM */
|
||||
uint8_t pin; /* which interrupt pin this device uses */
|
||||
|
||||
// struct pci_driver *driver; /* which driver has allocated this device */
|
||||
uint64_t dma_mask; /* Mask of the bits of bus address this
|
||||
device implements. Normally this is
|
||||
0xffffffff. You only need to change
|
||||
this if your device has broken DMA
|
||||
or supports 64-bit transfers. */
|
||||
|
||||
// struct device_dma_parameters dma_parms;
|
||||
|
||||
// pci_power_t current_state; /* Current operating state. In ACPI-speak,
|
||||
// this is D0-D3, D0 being fully functional,
|
||||
// and D3 being off. */
|
||||
// int pm_cap; /* PM capability offset in the
|
||||
// configuration space */
|
||||
unsigned int pme_support:5; /* Bitmask of states from which PME#
|
||||
can be generated */
|
||||
unsigned int d1_support:1; /* Low power state D1 is supported */
|
||||
unsigned int d2_support:1; /* Low power state D2 is supported */
|
||||
unsigned int no_d1d2:1; /* Only allow D0 and D3 */
|
||||
|
||||
// pci_channel_state_t error_state; /* current connectivity state */
|
||||
// struct device dev; /* Generic device interface */
|
||||
|
||||
// int cfg_size; /* Size of configuration space */
|
||||
|
||||
/*
|
||||
* Instead of touching interrupt line and base address registers
|
||||
* directly, use the values stored here. They might be different!
|
||||
*/
|
||||
unsigned int irq;
|
||||
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
|
||||
|
||||
/* These fields are used by common fixups */
|
||||
unsigned int transparent:1; /* Transparent PCI bridge */
|
||||
unsigned int multifunction:1;/* Part of multi-function device */
|
||||
/* keep track of device state */
|
||||
unsigned int is_added:1;
|
||||
unsigned int is_busmaster:1; /* device is busmaster */
|
||||
unsigned int no_msi:1; /* device may not use msi */
|
||||
unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
|
||||
unsigned int broken_parity_status:1; /* Device generates false positive parity */
|
||||
unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
|
||||
unsigned int msi_enabled:1;
|
||||
unsigned int msix_enabled:1;
|
||||
unsigned int ari_enabled:1; /* ARI forwarding */
|
||||
unsigned int is_managed:1;
|
||||
unsigned int is_pcie:1;
|
||||
unsigned int state_saved:1;
|
||||
unsigned int is_physfn:1;
|
||||
unsigned int is_virtfn:1;
|
||||
// pci_dev_flags_t dev_flags;
|
||||
// atomic_t enable_cnt; /* pci_enable_device has been called */
|
||||
|
||||
// u32 saved_config_space[16]; /* config space saved at suspend time */
|
||||
// struct hlist_head saved_cap_space;
|
||||
// struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
|
||||
// int rom_attr_enabled; /* has display of the rom attribute been enabled? */
|
||||
// struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
|
||||
// struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
|
||||
};
|
||||
|
||||
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
|
||||
#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
|
||||
#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
|
||||
#define pci_resource_len(dev,bar) \
|
||||
((pci_resource_start((dev), (bar)) == 0 && \
|
||||
pci_resource_end((dev), (bar)) == \
|
||||
pci_resource_start((dev), (bar))) ? 0 : \
|
||||
\
|
||||
(pci_resource_end((dev), (bar)) - \
|
||||
pci_resource_start((dev), (bar)) + 1))
|
||||
|
||||
struct pci_device_id
|
||||
{
|
||||
u16_t vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
|
||||
u16_t subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
|
||||
u32_t class, class_mask; /* (class,subclass,prog-if) triplet */
|
||||
u32_t driver_data; /* Data private to the driver */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct list_head link;
|
||||
struct pci_dev pci_dev;
|
||||
}dev_t;
|
||||
|
||||
int enum_pci_devices(void);
|
||||
|
||||
struct pci_device_id*
|
||||
find_pci_device(dev_t* pdev, struct pci_device_id *idlist);
|
||||
|
||||
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
|
||||
|
||||
int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
|
||||
|
||||
|
||||
#define pci_name(x) "radeon"
|
||||
|
||||
#endif //__PCI__H__
|
||||
|
||||
|
||||
351
drivers/video/drm/include/syscall.h
Normal file
351
drivers/video/drm/include/syscall.h
Normal file
@@ -0,0 +1,351 @@
|
||||
|
||||
#ifndef __SYSCALL_H__
|
||||
#define __SYSCALL_H__
|
||||
|
||||
|
||||
#define OS_BASE 0x80000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t handle;
|
||||
u32_t io_code;
|
||||
void *input;
|
||||
int inp_size;
|
||||
void *output;
|
||||
int out_size;
|
||||
}ioctl_t;
|
||||
|
||||
typedef int (__stdcall *srv_proc_t)(ioctl_t *);
|
||||
|
||||
#define ERR_OK 0
|
||||
#define ERR_PARAM -1
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int)__asm__("_drvEntry");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STDCALL __attribute__ ((stdcall)) __attribute__ ((dllimport))
|
||||
#define IMPORT __attribute__ ((dllimport))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SysMsgBoardStr __SysMsgBoardStr
|
||||
#define PciApi __PciApi
|
||||
//#define RegService __RegService
|
||||
#define CreateObject __CreateObject
|
||||
#define DestroyObject __DestroyObject
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PG_SW 0x003
|
||||
#define PG_NOCACHE 0x018
|
||||
|
||||
void* STDCALL AllocKernelSpace(size_t size)__asm__("AllocKernelSpace");
|
||||
void* STDCALL KernelAlloc(size_t size)__asm__("KernelAlloc");
|
||||
void* STDCALL KernelFree(void *mem)__asm__("KernelFree");
|
||||
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc");
|
||||
int STDCALL UserFree(void *mem)__asm__("UserFree");
|
||||
|
||||
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages");
|
||||
|
||||
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer");
|
||||
|
||||
u32_t STDCALL RegService(char *name, srv_proc_t proc)__asm__("RegService");
|
||||
|
||||
int STDCALL AttachIntHandler(int irq, void *handler, u32_t access) __asm__("AttachIntHandler");
|
||||
|
||||
|
||||
//void *CreateObject(u32 pid, size_t size);
|
||||
//void *DestroyObject(void *obj);
|
||||
|
||||
addr_t STDCALL MapIoMem(addr_t base, size_t size, u32_t flags)__asm__("MapIoMem");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void STDCALL SetMouseData(int btn, int x, int y,
|
||||
int z, int h)__asm__("SetMouseData");
|
||||
|
||||
static u32_t PciApi(int cmd);
|
||||
|
||||
u8_t STDCALL PciRead8 (u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead8");
|
||||
u16_t STDCALL PciRead16(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead16");
|
||||
u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
|
||||
|
||||
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8");
|
||||
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");
|
||||
u32_t STDCALL PciWrite32(u32_t bus, u32_t devfn, u32_t reg,u32_t val)__asm__("PciWrite32");
|
||||
|
||||
#define pciReadByte(tag, reg) \
|
||||
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadWord(tag, reg) \
|
||||
PciRead16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciReadLong(tag, reg) \
|
||||
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
|
||||
|
||||
#define pciWriteByte(tag, reg, val) \
|
||||
PciWrite8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteWord(tag, reg, val) \
|
||||
PciWrite16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
#define pciWriteLong(tag, reg, val) \
|
||||
PciWrite32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int dbg_open(char *path);
|
||||
int dbgprintf(const char* format, ...);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern inline int GetScreenSize()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(1));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenBpp()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(2));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenPitch()
|
||||
{
|
||||
int retval;
|
||||
|
||||
asm("int $0x40"
|
||||
:"=a"(retval)
|
||||
:"a"(61), "b"(3));
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline u32_t GetPgAddr(void *mem)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__GetPgAddr \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (mem) );
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CommitPages"
|
||||
::"a" (page), "b"(mem),"c"(size>>12)
|
||||
:"edx" );
|
||||
__asm__ __volatile__ ("":::"eax","ebx","ecx");
|
||||
};
|
||||
|
||||
extern inline void UnmapPages(void *mem, size_t size)
|
||||
{
|
||||
size = (size+4095) & ~4095;
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__UnmapPages"
|
||||
::"a" (mem), "c"(size>>12)
|
||||
:"edx");
|
||||
__asm__ __volatile__ ("":::"eax","ecx");
|
||||
};
|
||||
|
||||
extern inline void usleep(u32_t delay)
|
||||
{
|
||||
if( !delay )
|
||||
delay++;
|
||||
delay*=1000;
|
||||
|
||||
while(delay--)
|
||||
__asm__ __volatile__ (
|
||||
"xorl %%eax, %%eax \n\t"
|
||||
"cpuid \n\t"
|
||||
:::"eax","ebx","ecx","edx");
|
||||
};
|
||||
|
||||
static inline void udelay(u32_t delay)
|
||||
{
|
||||
if(!delay) delay++;
|
||||
delay*=500;
|
||||
|
||||
while(delay--)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"xorl %%eax, %%eax \n\t"
|
||||
"cpuid"
|
||||
:::"eax","ebx","ecx","edx" );
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mdelay(u32_t time)
|
||||
{
|
||||
time /= 10;
|
||||
if(!time) time = 1;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__Delay"
|
||||
::"b" (time));
|
||||
__asm__ __volatile__ (
|
||||
"":::"ebx");
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern inline u32_t __PciApi(int cmd)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__PciApi"
|
||||
:"=a" (retval)
|
||||
:"a" (cmd)
|
||||
:"memory");
|
||||
return retval;
|
||||
};
|
||||
|
||||
extern inline void* __CreateObject(u32_t pid, size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__CreateObject \n\t"
|
||||
:"=a" (retval)
|
||||
:"a" (size),"b"(pid)
|
||||
:"esi","edi", "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline void *__DestroyObject(void *obj)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__DestroyObject"
|
||||
:
|
||||
:"a" (obj)
|
||||
:"ebx","edx","esi","edi", "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
u32 __RegService(char *name, srv_proc_t proc)
|
||||
{
|
||||
u32 retval;
|
||||
|
||||
asm __volatile__
|
||||
(
|
||||
"pushl %%eax \n\t"
|
||||
"pushl %%ebx \n\t"
|
||||
"call *__imp__RegService \n\t"
|
||||
:"=eax" (retval)
|
||||
:"a" (proc), "b" (name)
|
||||
:"memory"
|
||||
);
|
||||
return retval;
|
||||
};
|
||||
*/
|
||||
|
||||
extern inline u32_t safe_cli(void)
|
||||
{
|
||||
u32_t ifl;
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"popl %0\n\t"
|
||||
"cli\n"
|
||||
: "=r" (ifl));
|
||||
return ifl;
|
||||
}
|
||||
|
||||
extern inline void safe_sti(u32_t ifl)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"pushl %0\n\t"
|
||||
"popf\n"
|
||||
: : "r" (ifl)
|
||||
);
|
||||
}
|
||||
|
||||
extern inline void __clear (void * dst, unsigned len)
|
||||
{
|
||||
u32_t tmp;
|
||||
__asm__ __volatile__ (
|
||||
// "xorl %%eax, %%eax \n\t"
|
||||
"cld \n\t"
|
||||
"rep stosb \n"
|
||||
:"=c"(tmp),"=D"(tmp)
|
||||
:"a"(0),"c"(len),"D"(dst));
|
||||
__asm__ __volatile__ ("":::"ecx","edi");
|
||||
};
|
||||
|
||||
extern inline void out8(const u16_t port, const u8_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outb %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline void out16(const u16_t port, const u16_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outw %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline void out32(const u16_t port, const u32_t val)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
("outl %1, %0\n" : : "dN"(port), "a"(val));
|
||||
}
|
||||
|
||||
extern inline u8_t in8(const u16_t port)
|
||||
{
|
||||
u8_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inb %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline u16_t in16(const u16_t port)
|
||||
{
|
||||
u16_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inw %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline u32_t in32(const u16_t port)
|
||||
{
|
||||
u32_t tmp;
|
||||
__asm__ __volatile__
|
||||
("inl %1, %0\n" : "=a"(tmp) : "dN"(port));
|
||||
return tmp;
|
||||
};
|
||||
|
||||
extern inline void delay(int time)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__Delay"
|
||||
::"b" (time));
|
||||
__asm__ __volatile__ (
|
||||
"":::"ebx");
|
||||
|
||||
}
|
||||
|
||||
extern inline void change_task()
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"call *__imp__ChangeTask");
|
||||
}
|
||||
|
||||
int drm_order(unsigned long size);
|
||||
|
||||
#endif
|
||||
236
drivers/video/drm/include/types.h
Normal file
236
drivers/video/drm/include/types.h
Normal file
@@ -0,0 +1,236 @@
|
||||
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
|
||||
typedef int bool;
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef unsigned int count_t;
|
||||
typedef unsigned int addr_t;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef unsigned char __u8;
|
||||
typedef unsigned short __u16;
|
||||
typedef unsigned int __u32;
|
||||
typedef unsigned long long __u64;
|
||||
|
||||
typedef signed char __s8;
|
||||
typedef signed short __s16;
|
||||
typedef signed int __s32;
|
||||
typedef signed long long __s64;
|
||||
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef unsigned char u8_t;
|
||||
typedef unsigned short u16_t;
|
||||
typedef unsigned int u32_t;
|
||||
typedef unsigned long long u64_t;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed long long int64_t;
|
||||
|
||||
#define NULL (void*)0
|
||||
|
||||
typedef uint32_t dma_addr_t;
|
||||
typedef uint32_t resource_size_t;
|
||||
|
||||
#define __user
|
||||
|
||||
#define cpu_to_le16(v16) (v16)
|
||||
#define cpu_to_le32(v32) (v32)
|
||||
#define cpu_to_le64(v64) (v64)
|
||||
#define le16_to_cpu(v16) (v16)
|
||||
#define le32_to_cpu(v32) (v32)
|
||||
#define le64_to_cpu(v64) (v64)
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define BITS_PER_LONG 32
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
|
||||
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
|
||||
#define KERN_EMERG "<0>" /* system is unusable */
|
||||
#define KERN_ALERT "<1>" /* action must be taken immediately */
|
||||
#define KERN_CRIT "<2>" /* critical conditions */
|
||||
#define KERN_ERR "<3>" /* error conditions */
|
||||
#define KERN_WARNING "<4>" /* warning conditions */
|
||||
#define KERN_NOTICE "<5>" /* normal but significant condition */
|
||||
#define KERN_INFO "<6>" /* informational */
|
||||
#define KERN_DEBUG "<7>" /* debug-level messages */
|
||||
|
||||
//int printk(const char *fmt, ...);
|
||||
|
||||
#define printk(fmt, arg...) dbgprintf(fmt , ##arg)
|
||||
|
||||
|
||||
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
|
||||
|
||||
#define DRM_INFO(fmt, arg...) dbgprintf("DRM: "fmt , ##arg)
|
||||
|
||||
#define DRM_ERROR(fmt, arg...) \
|
||||
printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg)
|
||||
|
||||
#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
|
||||
|
||||
#define __must_be_array(a) \
|
||||
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_ARCH_BUG
|
||||
#define BUG() do { \
|
||||
printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
|
||||
/* panic("BUG!"); */ \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ARCH_BUG_ON
|
||||
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define MTRR_TYPE_UNCACHABLE 0
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
#define MTRR_TYPE_WRTHROUGH 4
|
||||
#define MTRR_TYPE_WRPROT 5
|
||||
#define MTRR_TYPE_WRBACK 6
|
||||
#define MTRR_NUM_TYPES 7
|
||||
|
||||
int dbgprintf(const char* format, ...);
|
||||
|
||||
#define GFP_KERNEL 0
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
int snprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
|
||||
//#include <string.h>
|
||||
|
||||
void* memcpy(void *s1, const void *s2, size_t n);
|
||||
void* memset(void *s, int c, size_t n);
|
||||
size_t strlen(const char *s);
|
||||
char *strcpy(char *s1, const char *s2);
|
||||
char *strncpy (char *dst, const char *src, size_t len);
|
||||
|
||||
void *malloc(size_t size);
|
||||
|
||||
#define kmalloc(s,f) malloc((s))
|
||||
#define kfree free
|
||||
|
||||
static inline void *kzalloc(size_t size, u32_t flags)
|
||||
{
|
||||
void *ret = malloc(size);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct drm_file;
|
||||
|
||||
#define offsetof(TYPE,MEMBER) __builtin_offsetof(TYPE,MEMBER)
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
|
||||
|
||||
#define DRM_MEMORYBARRIER() __asm__ __volatile__("lock; addl $0,0(%esp)")
|
||||
#define mb() __asm__ __volatile__("lock; addl $0,0(%esp)")
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
|
||||
static inline void bitmap_zero(unsigned long *dst, int nbits)
|
||||
{
|
||||
if (nbits <= BITS_PER_LONG)
|
||||
*dst = 0UL;
|
||||
else {
|
||||
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
#define EXPORT_SYMBOL(x)
|
||||
|
||||
#define min(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x < _y ? _x : _y; })
|
||||
|
||||
#define max(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x > _y ? _x : _y; })
|
||||
|
||||
|
||||
extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
|
||||
|
||||
# define do_div(n,base) ({ \
|
||||
uint32_t __base = (base); \
|
||||
uint32_t __rem; \
|
||||
(void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
|
||||
if (likely(((n) >> 32) == 0)) { \
|
||||
__rem = (uint32_t)(n) % __base; \
|
||||
(n) = (uint32_t)(n) / __base; \
|
||||
} else \
|
||||
__rem = __div64_32(&(n), __base); \
|
||||
__rem; \
|
||||
})
|
||||
|
||||
#define lower_32_bits(n) ((u32)(n))
|
||||
|
||||
#define INT_MAX ((int)(~0U>>1))
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#define UINT_MAX (~0U)
|
||||
#define LONG_MAX ((long)(~0UL>>1))
|
||||
#define LONG_MIN (-LONG_MAX - 1)
|
||||
#define ULONG_MAX (~0UL)
|
||||
#define LLONG_MAX ((long long)(~0ULL>>1))
|
||||
#define LLONG_MIN (-LLONG_MAX - 1)
|
||||
#define ULLONG_MAX (~0ULL)
|
||||
|
||||
|
||||
static inline void *kcalloc(size_t n, size_t size, u32_t flags)
|
||||
{
|
||||
if (n != 0 && size > ULONG_MAX / n)
|
||||
return NULL;
|
||||
return kzalloc(n * size, 0);
|
||||
}
|
||||
|
||||
#define ENTRY() dbgprintf("enter %s\n",__FUNCTION__)
|
||||
#define LEAVE() dbgprintf("leave %s\n",__FUNCTION__)
|
||||
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
|
||||
#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159
|
||||
|
||||
#endif //__TYPES_H__
|
||||
578
drivers/video/drm/radeon/ObjectID.h
Normal file
578
drivers/video/drm/radeon/ObjectID.h
Normal file
@@ -0,0 +1,578 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.
|
||||
*/
|
||||
/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */
|
||||
|
||||
#ifndef _OBJECTID_H
|
||||
#define _OBJECTID_H
|
||||
|
||||
#if defined(_X86_)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object Type Definition */
|
||||
/****************************************************/
|
||||
#define GRAPH_OBJECT_TYPE_NONE 0x0
|
||||
#define GRAPH_OBJECT_TYPE_GPU 0x1
|
||||
#define GRAPH_OBJECT_TYPE_ENCODER 0x2
|
||||
#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3
|
||||
#define GRAPH_OBJECT_TYPE_ROUTER 0x4
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Encoder Object ID Definition */
|
||||
/****************************************************/
|
||||
#define ENCODER_OBJECT_ID_NONE 0x00
|
||||
|
||||
/* Radeon Class Display Hardware */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07
|
||||
|
||||
/* External Third Party Encoders */
|
||||
#define ENCODER_OBJECT_ID_SI170B 0x08
|
||||
#define ENCODER_OBJECT_ID_CH7303 0x09
|
||||
#define ENCODER_OBJECT_ID_CH7301 0x0A
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */
|
||||
#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C
|
||||
#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D
|
||||
#define ENCODER_OBJECT_ID_TITFP513 0x0E
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */
|
||||
#define ENCODER_OBJECT_ID_VT1623 0x10
|
||||
#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11
|
||||
#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12
|
||||
/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */
|
||||
#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */
|
||||
#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19
|
||||
#define ENCODER_OBJECT_ID_VT1625 0x1A
|
||||
#define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B
|
||||
#define ENCODER_OBJECT_ID_DP_AN9801 0x1C
|
||||
#define ENCODER_OBJECT_ID_DP_DP501 0x1D
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY 0x1E
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21
|
||||
|
||||
#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID Definition */
|
||||
/****************************************************/
|
||||
#define CONNECTOR_OBJECT_ID_NONE 0x00
|
||||
#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01
|
||||
#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02
|
||||
#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03
|
||||
#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D 0x04
|
||||
#define CONNECTOR_OBJECT_ID_VGA 0x05
|
||||
#define CONNECTOR_OBJECT_ID_COMPOSITE 0x06
|
||||
#define CONNECTOR_OBJECT_ID_SVIDEO 0x07
|
||||
#define CONNECTOR_OBJECT_ID_YPbPr 0x08
|
||||
#define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09
|
||||
#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */
|
||||
#define CONNECTOR_OBJECT_ID_SCART 0x0B
|
||||
#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C
|
||||
#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D
|
||||
#define CONNECTOR_OBJECT_ID_LVDS 0x0E
|
||||
#define CONNECTOR_OBJECT_ID_7PIN_DIN 0x0F
|
||||
#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR 0x10
|
||||
#define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11
|
||||
#define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12
|
||||
#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13
|
||||
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Router Object ID Definition */
|
||||
/****************************************************/
|
||||
#define ROUTER_OBJECT_ID_NONE 0x00
|
||||
#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object ENUM ID Definition */
|
||||
/****************************************************/
|
||||
#define GRAPH_OBJECT_ENUM_ID1 0x01
|
||||
#define GRAPH_OBJECT_ENUM_ID2 0x02
|
||||
#define GRAPH_OBJECT_ENUM_ID3 0x03
|
||||
#define GRAPH_OBJECT_ENUM_ID4 0x04
|
||||
#define GRAPH_OBJECT_ENUM_ID5 0x05
|
||||
#define GRAPH_OBJECT_ENUM_ID6 0x06
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object ID Bit definition */
|
||||
/****************************************************/
|
||||
#define OBJECT_ID_MASK 0x00FF
|
||||
#define ENUM_ID_MASK 0x0700
|
||||
#define RESERVED1_ID_MASK 0x0800
|
||||
#define OBJECT_TYPE_MASK 0x7000
|
||||
#define RESERVED2_ID_MASK 0x8000
|
||||
|
||||
#define OBJECT_ID_SHIFT 0x00
|
||||
#define ENUM_ID_SHIFT 0x08
|
||||
#define OBJECT_TYPE_SHIFT 0x0C
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object family definition */
|
||||
/****************************************************/
|
||||
#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) \
|
||||
(GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
|
||||
GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT)
|
||||
/****************************************************/
|
||||
/* GPU Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define GPU_ENUM_ID1 (GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Encoder Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
/*
|
||||
#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101
|
||||
#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102
|
||||
#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103
|
||||
#define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104
|
||||
#define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106
|
||||
#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107
|
||||
#define ENCODER_SIL170B_ENUM_ID1 0x2108
|
||||
#define ENCODER_CH7303_ENUM_ID1 0x2109
|
||||
#define ENCODER_CH7301_ENUM_ID1 0x210A
|
||||
#define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 0x210C
|
||||
#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 0x210D
|
||||
#define ENCODER_TITFP513_ENUM_ID1 0x210E
|
||||
#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 0x210F
|
||||
#define ENCODER_VT1623_ENUM_ID1 0x2110
|
||||
#define ENCODER_HDMI_SI1930_ENUM_ID1 0x2111
|
||||
#define ENCODER_HDMI_INTERNAL_ENUM_ID1 0x2112
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113
|
||||
#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116
|
||||
#define ENCODER_SI178_ENUM_ID1 0x2117
|
||||
#define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118
|
||||
#define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119
|
||||
#define ENCODER_VT1625_ENUM_ID1 0x211A
|
||||
#define ENCODER_HDMI_SI1932_ENUM_ID1 0x211B
|
||||
#define ENCODER_ENCODER_DP_AN9801_ENUM_ID1 0x211C
|
||||
#define ENCODER_DP_DP501_ENUM_ID1 0x211D
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E
|
||||
*/
|
||||
#define ENCODER_INTERNAL_LVDS_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DAC1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DAC2_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_SIL170B_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_CH7303_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_CH7301_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DVO1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_TITFP513_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_VT1623_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_SI1930_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_INTERNAL_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) /* Shared with CV/TV and CRT */
|
||||
|
||||
#define ENCODER_SI178_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_MVPU_FPGA_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DDI_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_VT1625_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_SI1932_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_DP_DP501_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_DP_AN9801_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
/*
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 0x3101
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 0x3102
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 0x3103
|
||||
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 0x3104
|
||||
#define CONNECTOR_VGA_ENUM_ID1 0x3105
|
||||
#define CONNECTOR_COMPOSITE_ENUM_ID1 0x3106
|
||||
#define CONNECTOR_SVIDEO_ENUM_ID1 0x3107
|
||||
#define CONNECTOR_YPbPr_ENUM_ID1 0x3108
|
||||
#define CONNECTOR_D_CONNECTORE_ENUM_ID1 0x3109
|
||||
#define CONNECTOR_9PIN_DIN_ENUM_ID1 0x310A
|
||||
#define CONNECTOR_SCART_ENUM_ID1 0x310B
|
||||
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 0x310C
|
||||
#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 0x310D
|
||||
#define CONNECTOR_LVDS_ENUM_ID1 0x310E
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110
|
||||
*/
|
||||
#define CONNECTOR_LVDS_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_VGA_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_VGA_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_COMPOSITE_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SVIDEO_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_YPbPr_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_D_CONNECTOR_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_9PIN_DIN_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SCART_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_CROSSFIRE_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_CROSSFIRE_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID2 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID3 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID4 \
|
||||
(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Router Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 \
|
||||
(GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
|
||||
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Object Cap definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define GRAPHICS_OBJECT_CAP_I2C 0x00000001L
|
||||
#define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L
|
||||
|
||||
#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01
|
||||
#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02
|
||||
#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03
|
||||
|
||||
#if defined(_X86_)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#endif /*GRAPHICTYPE */
|
||||
55
drivers/video/drm/radeon/atikms.lds
Normal file
55
drivers/video/drm/radeon/atikms.lds
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
OUTPUT_FORMAT(pei-i386)
|
||||
|
||||
ENTRY("_drvEntry")
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = SIZEOF_HEADERS;
|
||||
. = ALIGN(__section_alignment__);
|
||||
|
||||
.text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
|
||||
|
||||
{
|
||||
*(.text) *(.rdata)
|
||||
}
|
||||
|
||||
.data ALIGN(__section_alignment__) :
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.reloc ALIGN(__section_alignment__) :
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
|
||||
.idata ALIGN(__section_alignment__):
|
||||
{
|
||||
SORT(*)(.idata$2)
|
||||
SORT(*)(.idata$3)
|
||||
/* These zeroes mark the end of the import list. */
|
||||
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
|
||||
SORT(*)(.idata$4)
|
||||
SORT(*)(.idata$5)
|
||||
SORT(*)(.idata$6)
|
||||
SORT(*)(.idata$7)
|
||||
}
|
||||
|
||||
.bss ALIGN(__section_alignment__):
|
||||
{
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.debug$S)
|
||||
*(.debug$T)
|
||||
*(.debug$F)
|
||||
*(.drectve)
|
||||
*(.edata)
|
||||
}
|
||||
}
|
||||
|
||||
48
drivers/video/drm/radeon/atom-bits.h
Normal file
48
drivers/video/drm/radeon/atom-bits.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_BITS_H
|
||||
#define ATOM_BITS_H
|
||||
|
||||
static inline uint8_t get_u8(void *bios, int ptr)
|
||||
{
|
||||
return ((unsigned char *)bios)[ptr];
|
||||
}
|
||||
#define U8(ptr) get_u8(ctx->ctx->bios, (ptr))
|
||||
#define CU8(ptr) get_u8(ctx->bios, (ptr))
|
||||
static inline uint16_t get_u16(void *bios, int ptr)
|
||||
{
|
||||
return get_u8(bios ,ptr)|(((uint16_t)get_u8(bios, ptr+1))<<8);
|
||||
}
|
||||
#define U16(ptr) get_u16(ctx->ctx->bios, (ptr))
|
||||
#define CU16(ptr) get_u16(ctx->bios, (ptr))
|
||||
static inline uint32_t get_u32(void *bios, int ptr)
|
||||
{
|
||||
return get_u16(bios, ptr)|(((uint32_t)get_u16(bios, ptr+2))<<16);
|
||||
}
|
||||
#define U32(ptr) get_u32(ctx->ctx->bios, (ptr))
|
||||
#define CU32(ptr) get_u32(ctx->bios, (ptr))
|
||||
#define CSTR(ptr) (((char *)(ctx->bios))+(ptr))
|
||||
|
||||
#endif
|
||||
100
drivers/video/drm/radeon/atom-names.h
Normal file
100
drivers/video/drm/radeon/atom-names.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_NAMES_H
|
||||
#define ATOM_NAMES_H
|
||||
|
||||
#include "atom.h"
|
||||
|
||||
#ifdef ATOM_DEBUG
|
||||
|
||||
#define ATOM_OP_NAMES_CNT 123
|
||||
static char *atom_op_names[ATOM_OP_NAMES_CNT] = {
|
||||
"RESERVED", "MOVE_REG", "MOVE_PS", "MOVE_WS", "MOVE_FB", "MOVE_PLL",
|
||||
"MOVE_MC", "AND_REG", "AND_PS", "AND_WS", "AND_FB", "AND_PLL", "AND_MC",
|
||||
"OR_REG", "OR_PS", "OR_WS", "OR_FB", "OR_PLL", "OR_MC", "SHIFT_LEFT_REG",
|
||||
"SHIFT_LEFT_PS", "SHIFT_LEFT_WS", "SHIFT_LEFT_FB", "SHIFT_LEFT_PLL",
|
||||
"SHIFT_LEFT_MC", "SHIFT_RIGHT_REG", "SHIFT_RIGHT_PS", "SHIFT_RIGHT_WS",
|
||||
"SHIFT_RIGHT_FB", "SHIFT_RIGHT_PLL", "SHIFT_RIGHT_MC", "MUL_REG",
|
||||
"MUL_PS", "MUL_WS", "MUL_FB", "MUL_PLL", "MUL_MC", "DIV_REG", "DIV_PS",
|
||||
"DIV_WS", "DIV_FB", "DIV_PLL", "DIV_MC", "ADD_REG", "ADD_PS", "ADD_WS",
|
||||
"ADD_FB", "ADD_PLL", "ADD_MC", "SUB_REG", "SUB_PS", "SUB_WS", "SUB_FB",
|
||||
"SUB_PLL", "SUB_MC", "SET_ATI_PORT", "SET_PCI_PORT", "SET_SYS_IO_PORT",
|
||||
"SET_REG_BLOCK", "SET_FB_BASE", "COMPARE_REG", "COMPARE_PS",
|
||||
"COMPARE_WS", "COMPARE_FB", "COMPARE_PLL", "COMPARE_MC", "SWITCH",
|
||||
"JUMP", "JUMP_EQUAL", "JUMP_BELOW", "JUMP_ABOVE", "JUMP_BELOW_OR_EQUAL",
|
||||
"JUMP_ABOVE_OR_EQUAL", "JUMP_NOT_EQUAL", "TEST_REG", "TEST_PS", "TEST_WS",
|
||||
"TEST_FB", "TEST_PLL", "TEST_MC", "DELAY_MILLISEC", "DELAY_MICROSEC",
|
||||
"CALL_TABLE", "REPEAT", "CLEAR_REG", "CLEAR_PS", "CLEAR_WS", "CLEAR_FB",
|
||||
"CLEAR_PLL", "CLEAR_MC", "NOP", "EOT", "MASK_REG", "MASK_PS", "MASK_WS",
|
||||
"MASK_FB", "MASK_PLL", "MASK_MC", "POST_CARD", "BEEP", "SAVE_REG",
|
||||
"RESTORE_REG", "SET_DATA_BLOCK", "XOR_REG", "XOR_PS", "XOR_WS", "XOR_FB",
|
||||
"XOR_PLL", "XOR_MC", "SHL_REG", "SHL_PS", "SHL_WS", "SHL_FB", "SHL_PLL",
|
||||
"SHL_MC", "SHR_REG", "SHR_PS", "SHR_WS", "SHR_FB", "SHR_PLL", "SHR_MC",
|
||||
"DEBUG", "CTB_DS",
|
||||
};
|
||||
|
||||
#define ATOM_TABLE_NAMES_CNT 74
|
||||
static char *atom_table_names[ATOM_TABLE_NAMES_CNT] = {
|
||||
"ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit",
|
||||
"VRAM_BlockVenderDetection", "SetClocksRatio", "MemoryControllerInit",
|
||||
"GPIO_PinInit", "MemoryParamAdjust", "DVOEncoderControl",
|
||||
"GPIOPinControl", "SetEngineClock", "SetMemoryClock", "SetPixelClock",
|
||||
"DynamicClockGating", "ResetMemoryDLL", "ResetMemoryDevice",
|
||||
"MemoryPLLInit", "EnableMemorySelfRefresh", "AdjustMemoryController",
|
||||
"EnableASIC_StaticPwrMgt", "ASIC_StaticPwrMgtStatusChange",
|
||||
"DAC_LoadDetection", "TMDS2EncoderControl", "LCD1OutputControl",
|
||||
"DAC1EncoderControl", "DAC2EncoderControl", "DVOOutputControl",
|
||||
"CV1OutputControl", "SetCRTC_DPM_State", "TVEncoderControl",
|
||||
"TMDS1EncoderControl", "LVDSEncoderControl", "TV1OutputControl",
|
||||
"EnableScaler", "BlankCRTC", "EnableCRTC", "GetPixelClock",
|
||||
"EnableVGA_Render", "EnableVGA_Access", "SetCRTC_Timing",
|
||||
"SetCRTC_OverScan", "SetCRTC_Replication", "SelectCRTC_Source",
|
||||
"EnableGraphSurfaces", "UpdateCRTC_DoubleBufferRegisters",
|
||||
"LUT_AutoFill", "EnableHW_IconCursor", "GetMemoryClock",
|
||||
"GetEngineClock", "SetCRTC_UsingDTDTiming", "TVBootUpStdPinDetection",
|
||||
"DFP2OutputControl", "VRAM_BlockDetectionByStrap", "MemoryCleanUp",
|
||||
"ReadEDIDFromHWAssistedI2C", "WriteOneByteToHWAssistedI2C",
|
||||
"ReadHWAssistedI2CStatus", "SpeedFanControl", "PowerConnectorDetection",
|
||||
"MC_Synchronization", "ComputeMemoryEnginePLL", "MemoryRefreshConversion",
|
||||
"VRAM_GetCurrentInfoBlock", "DynamicMemorySettings", "MemoryTraining",
|
||||
"EnableLVDS_SS", "DFP1OutputControl", "SetVoltage", "CRT1OutputControl",
|
||||
"CRT2OutputControl", "SetupHWAssistedI2CStatus", "ClockSource",
|
||||
"MemoryDeviceInit", "EnableYUV",
|
||||
};
|
||||
|
||||
#define ATOM_IO_NAMES_CNT 5
|
||||
static char *atom_io_names[ATOM_IO_NAMES_CNT] = {
|
||||
"MM", "PLL", "MC", "PCIE", "PCIE PORT",
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define ATOM_OP_NAMES_CNT 0
|
||||
#define ATOM_TABLE_NAMES_CNT 0
|
||||
#define ATOM_IO_NAMES_CNT 0
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
42
drivers/video/drm/radeon/atom-types.h
Normal file
42
drivers/video/drm/radeon/atom-types.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2008 Red Hat 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.
|
||||
*
|
||||
* Author: Dave Airlie
|
||||
*/
|
||||
|
||||
#ifndef ATOM_TYPES_H
|
||||
#define ATOM_TYPES_H
|
||||
|
||||
/* sync atom types to kernel types */
|
||||
|
||||
typedef uint16_t USHORT;
|
||||
typedef uint32_t ULONG;
|
||||
typedef uint8_t UCHAR;
|
||||
|
||||
|
||||
#ifndef ATOM_BIG_ENDIAN
|
||||
#if defined(__BIG_ENDIAN)
|
||||
#define ATOM_BIG_ENDIAN 1
|
||||
#else
|
||||
#define ATOM_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
1221
drivers/video/drm/radeon/atom.c
Normal file
1221
drivers/video/drm/radeon/atom.c
Normal file
File diff suppressed because it is too large
Load Diff
149
drivers/video/drm/radeon/atom.h
Normal file
149
drivers/video/drm/radeon/atom.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_H
|
||||
#define ATOM_H
|
||||
|
||||
#include <types.h>
|
||||
#include "drmP.h"
|
||||
|
||||
#define ATOM_BIOS_MAGIC 0xAA55
|
||||
#define ATOM_ATI_MAGIC_PTR 0x30
|
||||
#define ATOM_ATI_MAGIC " 761295520"
|
||||
#define ATOM_ROM_TABLE_PTR 0x48
|
||||
|
||||
#define ATOM_ROM_MAGIC "ATOM"
|
||||
#define ATOM_ROM_MAGIC_PTR 4
|
||||
|
||||
#define ATOM_ROM_MSG_PTR 0x10
|
||||
#define ATOM_ROM_CMD_PTR 0x1E
|
||||
#define ATOM_ROM_DATA_PTR 0x20
|
||||
|
||||
#define ATOM_CMD_INIT 0
|
||||
#define ATOM_CMD_SETSCLK 0x0A
|
||||
#define ATOM_CMD_SETMCLK 0x0B
|
||||
#define ATOM_CMD_SETPCLK 0x0C
|
||||
|
||||
#define ATOM_DATA_FWI_PTR 0xC
|
||||
#define ATOM_DATA_IIO_PTR 0x32
|
||||
|
||||
#define ATOM_FWI_DEFSCLK_PTR 8
|
||||
#define ATOM_FWI_DEFMCLK_PTR 0xC
|
||||
#define ATOM_FWI_MAXSCLK_PTR 0x24
|
||||
#define ATOM_FWI_MAXMCLK_PTR 0x28
|
||||
|
||||
#define ATOM_CT_SIZE_PTR 0
|
||||
#define ATOM_CT_WS_PTR 4
|
||||
#define ATOM_CT_PS_PTR 5
|
||||
#define ATOM_CT_PS_MASK 0x7F
|
||||
#define ATOM_CT_CODE_PTR 6
|
||||
|
||||
#define ATOM_OP_CNT 123
|
||||
#define ATOM_OP_EOT 91
|
||||
|
||||
#define ATOM_CASE_MAGIC 0x63
|
||||
#define ATOM_CASE_END 0x5A5A
|
||||
|
||||
#define ATOM_ARG_REG 0
|
||||
#define ATOM_ARG_PS 1
|
||||
#define ATOM_ARG_WS 2
|
||||
#define ATOM_ARG_FB 3
|
||||
#define ATOM_ARG_ID 4
|
||||
#define ATOM_ARG_IMM 5
|
||||
#define ATOM_ARG_PLL 6
|
||||
#define ATOM_ARG_MC 7
|
||||
|
||||
#define ATOM_SRC_DWORD 0
|
||||
#define ATOM_SRC_WORD0 1
|
||||
#define ATOM_SRC_WORD8 2
|
||||
#define ATOM_SRC_WORD16 3
|
||||
#define ATOM_SRC_BYTE0 4
|
||||
#define ATOM_SRC_BYTE8 5
|
||||
#define ATOM_SRC_BYTE16 6
|
||||
#define ATOM_SRC_BYTE24 7
|
||||
|
||||
#define ATOM_WS_QUOTIENT 0x40
|
||||
#define ATOM_WS_REMAINDER 0x41
|
||||
#define ATOM_WS_DATAPTR 0x42
|
||||
#define ATOM_WS_SHIFT 0x43
|
||||
#define ATOM_WS_OR_MASK 0x44
|
||||
#define ATOM_WS_AND_MASK 0x45
|
||||
#define ATOM_WS_FB_WINDOW 0x46
|
||||
#define ATOM_WS_ATTRIBUTES 0x47
|
||||
|
||||
#define ATOM_IIO_NOP 0
|
||||
#define ATOM_IIO_START 1
|
||||
#define ATOM_IIO_READ 2
|
||||
#define ATOM_IIO_WRITE 3
|
||||
#define ATOM_IIO_CLEAR 4
|
||||
#define ATOM_IIO_SET 5
|
||||
#define ATOM_IIO_MOVE_INDEX 6
|
||||
#define ATOM_IIO_MOVE_ATTR 7
|
||||
#define ATOM_IIO_MOVE_DATA 8
|
||||
#define ATOM_IIO_END 9
|
||||
|
||||
#define ATOM_IO_MM 0
|
||||
#define ATOM_IO_PCI 1
|
||||
#define ATOM_IO_SYSIO 2
|
||||
#define ATOM_IO_IIO 0x80
|
||||
|
||||
struct card_info {
|
||||
struct drm_device *dev;
|
||||
void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */
|
||||
uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */
|
||||
void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */
|
||||
uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */
|
||||
void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */
|
||||
uint32_t (* pll_read)(struct card_info *, uint32_t); /* filled by driver */
|
||||
};
|
||||
|
||||
struct atom_context {
|
||||
struct card_info *card;
|
||||
void *bios;
|
||||
uint32_t cmd_table, data_table;
|
||||
uint16_t *iio;
|
||||
|
||||
uint16_t data_block;
|
||||
uint32_t fb_base;
|
||||
uint32_t divmul[2];
|
||||
uint16_t io_attr;
|
||||
uint16_t reg_block;
|
||||
uint8_t shift;
|
||||
int cs_equal, cs_above;
|
||||
int io_mode;
|
||||
};
|
||||
|
||||
extern int atom_debug;
|
||||
|
||||
struct atom_context *atom_parse(struct card_info *, void *);
|
||||
void atom_execute_table(struct atom_context *, int, uint32_t *);
|
||||
int atom_asic_init(struct atom_context *);
|
||||
void atom_destroy(struct atom_context *);
|
||||
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
|
||||
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
|
||||
#include "atom-types.h"
|
||||
#include "atombios.h"
|
||||
#include "ObjectID.h"
|
||||
|
||||
#endif
|
||||
4785
drivers/video/drm/radeon/atombios.h
Normal file
4785
drivers/video/drm/radeon/atombios.h
Normal file
File diff suppressed because it is too large
Load Diff
709
drivers/video/drm/radeon/atombios_crtc.c
Normal file
709
drivers/video/drm/radeon/atombios_crtc.c
Normal file
@@ -0,0 +1,709 @@
|
||||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat 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: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include <drmP.h>
|
||||
#include <drm_crtc_helper.h>
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_fixed.h"
|
||||
#include "radeon.h"
|
||||
#include "atom.h"
|
||||
#include "atom-bits.h"
|
||||
|
||||
static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int index =
|
||||
GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
|
||||
ENABLE_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucEnable = lock;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
|
||||
ENABLE_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucEnable = state;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
|
||||
ENABLE_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucEnable = state;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
|
||||
BLANK_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucBlanking = state;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, 1);
|
||||
atombios_enable_crtc(crtc, 1);
|
||||
atombios_blank_crtc(crtc, 0);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
atombios_blank_crtc(crtc, 1);
|
||||
atombios_enable_crtc(crtc, 0);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode != DRM_MODE_DPMS_OFF) {
|
||||
radeon_crtc_load_lut(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
|
||||
SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
|
||||
|
||||
conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size);
|
||||
conv_param.usH_Blanking_Time =
|
||||
cpu_to_le16(crtc_param->usH_Blanking_Time);
|
||||
conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size);
|
||||
conv_param.usV_Blanking_Time =
|
||||
cpu_to_le16(crtc_param->usV_Blanking_Time);
|
||||
conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset);
|
||||
conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
|
||||
conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset);
|
||||
conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
|
||||
conv_param.susModeMiscInfo.usAccess =
|
||||
cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
|
||||
conv_param.ucCRTC = crtc_param->ucCRTC;
|
||||
|
||||
printk("executing set crtc dtd timing\n");
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
|
||||
}
|
||||
|
||||
void atombios_crtc_set_timing(struct drm_crtc *crtc,
|
||||
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *
|
||||
crtc_param)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
|
||||
|
||||
conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total);
|
||||
conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp);
|
||||
conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart);
|
||||
conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
|
||||
conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total);
|
||||
conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp);
|
||||
conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart);
|
||||
conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
|
||||
conv_param.susModeMiscInfo.usAccess =
|
||||
cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
|
||||
conv_param.ucCRTC = crtc_param->ucCRTC;
|
||||
conv_param.ucOverscanRight = crtc_param->ucOverscanRight;
|
||||
conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft;
|
||||
conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom;
|
||||
conv_param.ucOverscanTop = crtc_param->ucOverscanTop;
|
||||
conv_param.ucReserved = crtc_param->ucReserved;
|
||||
|
||||
printk("executing set crtc timing\n");
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
|
||||
}
|
||||
|
||||
void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *encoder = NULL;
|
||||
struct radeon_encoder *radeon_encoder = NULL;
|
||||
uint8_t frev, crev;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
SET_PIXEL_CLOCK_PS_ALLOCATION args;
|
||||
PIXEL_CLOCK_PARAMETERS *spc1_ptr;
|
||||
PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
|
||||
PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
|
||||
uint32_t sclock = mode->clock;
|
||||
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
|
||||
struct radeon_pll *pll;
|
||||
int pll_flags = 0;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
if (ASIC_IS_AVIVO(rdev)) {
|
||||
uint32_t ss_cntl;
|
||||
|
||||
if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
|
||||
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
/* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
|
||||
if (radeon_crtc->crtc_id == 0) {
|
||||
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
|
||||
WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1);
|
||||
} else {
|
||||
ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
|
||||
WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1);
|
||||
}
|
||||
} else {
|
||||
pll_flags |= RADEON_PLL_LEGACY;
|
||||
|
||||
if (mode->clock > 200000) /* range limits??? */
|
||||
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
}
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->crtc == crtc) {
|
||||
if (!ASIC_IS_AVIVO(rdev)) {
|
||||
if (encoder->encoder_type !=
|
||||
DRM_MODE_ENCODER_DAC)
|
||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
if (!ASIC_IS_AVIVO(rdev)
|
||||
&& (encoder->encoder_type ==
|
||||
DRM_MODE_ENCODER_LVDS))
|
||||
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||
}
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
}
|
||||
}
|
||||
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
pll = &rdev->clock.p1pll;
|
||||
else
|
||||
pll = &rdev->clock.p2pll;
|
||||
|
||||
radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div,
|
||||
&ref_div, &post_div, pll_flags);
|
||||
|
||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
|
||||
&crev);
|
||||
|
||||
switch (frev) {
|
||||
case 1:
|
||||
switch (crev) {
|
||||
case 1:
|
||||
spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
|
||||
spc1_ptr->usPixelClock = cpu_to_le16(sclock);
|
||||
spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
|
||||
spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
|
||||
spc1_ptr->ucFracFbDiv = frac_fb_div;
|
||||
spc1_ptr->ucPostDiv = post_div;
|
||||
spc1_ptr->ucPpll =
|
||||
radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
|
||||
spc1_ptr->ucCRTC = radeon_crtc->crtc_id;
|
||||
spc1_ptr->ucRefDivSrc = 1;
|
||||
break;
|
||||
case 2:
|
||||
spc2_ptr =
|
||||
(PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
|
||||
spc2_ptr->usPixelClock = cpu_to_le16(sclock);
|
||||
spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
|
||||
spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
|
||||
spc2_ptr->ucFracFbDiv = frac_fb_div;
|
||||
spc2_ptr->ucPostDiv = post_div;
|
||||
spc2_ptr->ucPpll =
|
||||
radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
|
||||
spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
|
||||
spc2_ptr->ucRefDivSrc = 1;
|
||||
break;
|
||||
case 3:
|
||||
if (!encoder)
|
||||
return;
|
||||
spc3_ptr =
|
||||
(PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
|
||||
spc3_ptr->usPixelClock = cpu_to_le16(sclock);
|
||||
spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
|
||||
spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
|
||||
spc3_ptr->ucFracFbDiv = frac_fb_div;
|
||||
spc3_ptr->ucPostDiv = post_div;
|
||||
spc3_ptr->ucPpll =
|
||||
radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
|
||||
spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
|
||||
spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id;
|
||||
spc3_ptr->ucEncoderMode =
|
||||
atombios_get_encoder_mode(encoder);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d %d\n", frev, crev);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d %d\n", frev, crev);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("executing set pll\n");
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_framebuffer *radeon_fb;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
uint64_t fb_location;
|
||||
uint32_t fb_format, fb_pitch_pixels;
|
||||
|
||||
ENTRY();
|
||||
|
||||
if (!crtc->fb)
|
||||
return -EINVAL;
|
||||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
obj = radeon_fb->obj;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
//if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
|
||||
// return -EINVAL;
|
||||
//}
|
||||
|
||||
fb_location = 0; //rdev->mc.vram_location;
|
||||
|
||||
dbgprintf("fb_location %x\n", fb_location);
|
||||
dbgprintf("bpp %x\n", crtc->fb->bits_per_pixel);
|
||||
|
||||
switch (crtc->fb->bits_per_pixel) {
|
||||
case 15:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
|
||||
AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
|
||||
break;
|
||||
case 16:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
|
||||
AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
|
||||
AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported screen depth %d\n",
|
||||
crtc->fb->bits_per_pixel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO tiling */
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
WREG32(AVIVO_D1VGA_CONTROL, 0);
|
||||
else
|
||||
WREG32(AVIVO_D2VGA_CONTROL, 0);
|
||||
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
(u32) fb_location);
|
||||
WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
|
||||
radeon_crtc->crtc_offset, (u32) fb_location);
|
||||
WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
|
||||
|
||||
WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
|
||||
WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
|
||||
|
||||
fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
|
||||
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
|
||||
WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
|
||||
|
||||
WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
|
||||
crtc->mode.vdisplay);
|
||||
x &= ~3;
|
||||
y &= ~1;
|
||||
WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
|
||||
(x << 16) | y);
|
||||
WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
||||
|
||||
if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
|
||||
AVIVO_D1MODE_INTERLEAVE_EN);
|
||||
else
|
||||
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
|
||||
|
||||
if (old_fb && old_fb != crtc->fb) {
|
||||
radeon_fb = to_radeon_framebuffer(old_fb);
|
||||
// radeon_gem_object_unpin(radeon_fb->obj);
|
||||
}
|
||||
LEAVE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int atombios_crtc_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y, struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *encoder;
|
||||
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
|
||||
|
||||
ENTRY();
|
||||
|
||||
/* TODO color tiling */
|
||||
memset(&crtc_timing, 0, sizeof(crtc_timing));
|
||||
|
||||
/* TODO tv */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
}
|
||||
|
||||
crtc_timing.ucCRTC = radeon_crtc->crtc_id;
|
||||
crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
|
||||
crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
|
||||
crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
|
||||
crtc_timing.usH_SyncWidth =
|
||||
adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
|
||||
|
||||
crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
|
||||
crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
|
||||
crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
|
||||
crtc_timing.usV_SyncWidth =
|
||||
adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
|
||||
|
||||
atombios_crtc_set_pll(crtc, adjusted_mode);
|
||||
atombios_crtc_set_timing(crtc, &crtc_timing);
|
||||
|
||||
if (ASIC_IS_AVIVO(rdev))
|
||||
atombios_crtc_set_base(crtc, x, y, old_fb);
|
||||
else {
|
||||
if (radeon_crtc->crtc_id == 0) {
|
||||
SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
|
||||
memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
|
||||
|
||||
/* setup FP shadow regs on R4xx */
|
||||
crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
|
||||
crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay;
|
||||
crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay;
|
||||
crtc_dtd_timing.usH_Blanking_Time =
|
||||
adjusted_mode->crtc_hblank_end -
|
||||
adjusted_mode->crtc_hdisplay;
|
||||
crtc_dtd_timing.usV_Blanking_Time =
|
||||
adjusted_mode->crtc_vblank_end -
|
||||
adjusted_mode->crtc_vdisplay;
|
||||
crtc_dtd_timing.usH_SyncOffset =
|
||||
adjusted_mode->crtc_hsync_start -
|
||||
adjusted_mode->crtc_hdisplay;
|
||||
crtc_dtd_timing.usV_SyncOffset =
|
||||
adjusted_mode->crtc_vsync_start -
|
||||
adjusted_mode->crtc_vdisplay;
|
||||
crtc_dtd_timing.usH_SyncWidth =
|
||||
adjusted_mode->crtc_hsync_end -
|
||||
adjusted_mode->crtc_hsync_start;
|
||||
crtc_dtd_timing.usV_SyncWidth =
|
||||
adjusted_mode->crtc_vsync_end -
|
||||
adjusted_mode->crtc_vsync_start;
|
||||
/* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */
|
||||
/* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
crtc_dtd_timing.susModeMiscInfo.usAccess |=
|
||||
ATOM_VSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
crtc_dtd_timing.susModeMiscInfo.usAccess |=
|
||||
ATOM_HSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
|
||||
crtc_dtd_timing.susModeMiscInfo.usAccess |=
|
||||
ATOM_COMPOSITESYNC;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
crtc_dtd_timing.susModeMiscInfo.usAccess |=
|
||||
ATOM_INTERLACE;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
crtc_dtd_timing.susModeMiscInfo.usAccess |=
|
||||
ATOM_DOUBLE_CLOCK_MODE;
|
||||
|
||||
atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing);
|
||||
}
|
||||
radeon_crtc_set_base(crtc, x, y, old_fb);
|
||||
radeon_legacy_atom_set_surface(crtc);
|
||||
}
|
||||
LEAVE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void atombios_crtc_prepare(struct drm_crtc *crtc)
|
||||
{
|
||||
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
atombios_lock_crtc(crtc, 1);
|
||||
}
|
||||
|
||||
static void atombios_crtc_commit(struct drm_crtc *crtc)
|
||||
{
|
||||
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
|
||||
atombios_lock_crtc(crtc, 0);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
|
||||
.dpms = atombios_crtc_dpms,
|
||||
.mode_fixup = atombios_crtc_mode_fixup,
|
||||
.mode_set = atombios_crtc_mode_set,
|
||||
.mode_set_base = atombios_crtc_set_base,
|
||||
.prepare = atombios_crtc_prepare,
|
||||
.commit = atombios_crtc_commit,
|
||||
};
|
||||
|
||||
void radeon_atombios_init_crtc(struct drm_device *dev,
|
||||
struct radeon_crtc *radeon_crtc)
|
||||
{
|
||||
if (radeon_crtc->crtc_id == 1)
|
||||
radeon_crtc->crtc_offset =
|
||||
AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
|
||||
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
|
||||
}
|
||||
|
||||
void radeon_init_disp_bw_avivo(struct drm_device *dev,
|
||||
struct drm_display_mode *mode1,
|
||||
uint32_t pixel_bytes1,
|
||||
struct drm_display_mode *mode2,
|
||||
uint32_t pixel_bytes2)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
fixed20_12 min_mem_eff;
|
||||
fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff;
|
||||
fixed20_12 sclk_ff, mclk_ff;
|
||||
uint32_t dc_lb_memory_split, temp;
|
||||
|
||||
min_mem_eff.full = rfixed_const_8(0);
|
||||
if (rdev->disp_priority == 2) {
|
||||
uint32_t mc_init_misc_lat_timer = 0;
|
||||
if (rdev->family == CHIP_RV515)
|
||||
mc_init_misc_lat_timer =
|
||||
RREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER);
|
||||
else if (rdev->family == CHIP_RS690)
|
||||
mc_init_misc_lat_timer =
|
||||
RREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER);
|
||||
|
||||
mc_init_misc_lat_timer &=
|
||||
~(R300_MC_DISP1R_INIT_LAT_MASK <<
|
||||
R300_MC_DISP1R_INIT_LAT_SHIFT);
|
||||
mc_init_misc_lat_timer &=
|
||||
~(R300_MC_DISP0R_INIT_LAT_MASK <<
|
||||
R300_MC_DISP0R_INIT_LAT_SHIFT);
|
||||
|
||||
if (mode2)
|
||||
mc_init_misc_lat_timer |=
|
||||
(1 << R300_MC_DISP1R_INIT_LAT_SHIFT);
|
||||
if (mode1)
|
||||
mc_init_misc_lat_timer |=
|
||||
(1 << R300_MC_DISP0R_INIT_LAT_SHIFT);
|
||||
|
||||
if (rdev->family == CHIP_RV515)
|
||||
WREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER,
|
||||
mc_init_misc_lat_timer);
|
||||
else if (rdev->family == CHIP_RS690)
|
||||
WREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER,
|
||||
mc_init_misc_lat_timer);
|
||||
}
|
||||
|
||||
/*
|
||||
* determine is there is enough bw for current mode
|
||||
*/
|
||||
temp_ff.full = rfixed_const(100);
|
||||
mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
|
||||
mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
|
||||
sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
|
||||
sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
|
||||
|
||||
temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
|
||||
temp_ff.full = rfixed_const(temp);
|
||||
mem_bw.full = rfixed_mul(mclk_ff, temp_ff);
|
||||
mem_bw.full = rfixed_mul(mem_bw, min_mem_eff);
|
||||
|
||||
pix_clk.full = 0;
|
||||
pix_clk2.full = 0;
|
||||
peak_disp_bw.full = 0;
|
||||
if (mode1) {
|
||||
temp_ff.full = rfixed_const(1000);
|
||||
pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */
|
||||
pix_clk.full = rfixed_div(pix_clk, temp_ff);
|
||||
temp_ff.full = rfixed_const(pixel_bytes1);
|
||||
peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff);
|
||||
}
|
||||
if (mode2) {
|
||||
temp_ff.full = rfixed_const(1000);
|
||||
pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */
|
||||
pix_clk2.full = rfixed_div(pix_clk2, temp_ff);
|
||||
temp_ff.full = rfixed_const(pixel_bytes2);
|
||||
peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff);
|
||||
}
|
||||
|
||||
if (peak_disp_bw.full >= mem_bw.full) {
|
||||
DRM_ERROR
|
||||
("You may not have enough display bandwidth for current mode\n"
|
||||
"If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
|
||||
printk("peak disp bw %d, mem_bw %d\n",
|
||||
rfixed_trunc(peak_disp_bw), rfixed_trunc(mem_bw));
|
||||
}
|
||||
|
||||
/*
|
||||
* Line Buffer Setup
|
||||
* There is a single line buffer shared by both display controllers.
|
||||
* DC_LB_MEMORY_SPLIT controls how that line buffer is shared between the display
|
||||
* controllers. The paritioning can either be done manually or via one of four
|
||||
* preset allocations specified in bits 1:0:
|
||||
* 0 - line buffer is divided in half and shared between each display controller
|
||||
* 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
|
||||
* 2 - D1 gets the whole buffer
|
||||
* 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
|
||||
* Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual allocation mode.
|
||||
* In manual allocation mode, D1 always starts at 0, D1 end/2 is specified in bits
|
||||
* 14:4; D2 allocation follows D1.
|
||||
*/
|
||||
|
||||
/* is auto or manual better ? */
|
||||
dc_lb_memory_split =
|
||||
RREG32(AVIVO_DC_LB_MEMORY_SPLIT) & ~AVIVO_DC_LB_MEMORY_SPLIT_MASK;
|
||||
dc_lb_memory_split &= ~AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
|
||||
#if 1
|
||||
/* auto */
|
||||
if (mode1 && mode2) {
|
||||
if (mode1->hdisplay > mode2->hdisplay) {
|
||||
if (mode1->hdisplay > 2560)
|
||||
dc_lb_memory_split |=
|
||||
AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
|
||||
else
|
||||
dc_lb_memory_split |=
|
||||
AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
|
||||
} else if (mode2->hdisplay > mode1->hdisplay) {
|
||||
if (mode2->hdisplay > 2560)
|
||||
dc_lb_memory_split |=
|
||||
AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
|
||||
else
|
||||
dc_lb_memory_split |=
|
||||
AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
|
||||
} else
|
||||
dc_lb_memory_split |=
|
||||
AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
|
||||
} else if (mode1) {
|
||||
dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY;
|
||||
} else if (mode2) {
|
||||
dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
|
||||
}
|
||||
#else
|
||||
/* manual */
|
||||
dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
|
||||
dc_lb_memory_split &=
|
||||
~(AVIVO_DC_LB_DISP1_END_ADR_MASK <<
|
||||
AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
|
||||
if (mode1) {
|
||||
dc_lb_memory_split |=
|
||||
((((mode1->hdisplay / 2) + 64) & AVIVO_DC_LB_DISP1_END_ADR_MASK)
|
||||
<< AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
|
||||
} else if (mode2) {
|
||||
dc_lb_memory_split |= (0 << AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
|
||||
}
|
||||
#endif
|
||||
WREG32(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split);
|
||||
}
|
||||
|
||||
|
||||
86
drivers/video/drm/radeon/makefile
Normal file
86
drivers/video/drm/radeon/makefile
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDFLAGS = -nostdlib -shared -s -Map atikms.map --image-base 0 --file-alignment 512 --section-alignment 4096
|
||||
|
||||
|
||||
DRM_TOPDIR = $(CURDIR)/..
|
||||
DRM_INCLUDES = $(DRM_TOPDIR)/include
|
||||
|
||||
LIBPATH:= .
|
||||
|
||||
LIBS:= -ldrv -lcore
|
||||
|
||||
NAME:= atikms
|
||||
|
||||
INCLUDES = -I $(DRM_INCLUDES) -I $(DRM_INCLUDES)/ttm
|
||||
|
||||
HFILES:= $(DRM_INCLUDES)/types.h \
|
||||
$(DRM_INCLUDES)/list.h \
|
||||
$(DRM_INCLUDES)/pci.h \
|
||||
$(DRM_INCLUDES)/drm.h \
|
||||
$(DRM_INCLUDES)/drmP.h \
|
||||
$(DRM_INCLUDES)/drm_edid.h \
|
||||
$(DRM_INCLUDES)/drm_crtc.h \
|
||||
$(DRM_INCLUDES)/drm_mode.h \
|
||||
$(DRM_INCLUDES)/drm_mm.h \
|
||||
atom.h \
|
||||
radeon.h \
|
||||
radeon_asic.h
|
||||
|
||||
NAME_SRC= \
|
||||
pci.c \
|
||||
$(DRM_TOPDIR)/drm_mm.c \
|
||||
$(DRM_TOPDIR)/drm_edid.c \
|
||||
$(DRM_TOPDIR)/drm_modes.c \
|
||||
$(DRM_TOPDIR)/drm_crtc.c \
|
||||
$(DRM_TOPDIR)/drm_crtc_helper.c \
|
||||
$(DRM_TOPDIR)/i2c/i2c-core.c \
|
||||
$(DRM_TOPDIR)/i2c/i2c-algo-bit.c \
|
||||
$(DRM_TOPDIR)/idr.c \
|
||||
radeon_gem.c \
|
||||
radeon_device.c \
|
||||
radeon_clocks.c \
|
||||
radeon_i2c.c \
|
||||
atom.c \
|
||||
radeon_atombios.c \
|
||||
atombios_crtc.c \
|
||||
radeon_encoders.c \
|
||||
radeon_connectors.c \
|
||||
radeon_bios.c \
|
||||
radeon_combios.c \
|
||||
radeon_legacy_crtc.c \
|
||||
radeon_legacy_encoders.c \
|
||||
radeon_display.c \
|
||||
radeon_object.c \
|
||||
radeon_gart.c \
|
||||
radeon_ring.c \
|
||||
r100.c \
|
||||
r300.c \
|
||||
r420.c \
|
||||
rv515.c \
|
||||
r520.c \
|
||||
r600.c \
|
||||
rs400.c \
|
||||
rs600.c \
|
||||
rs690.c \
|
||||
radeon_fb.c
|
||||
|
||||
|
||||
SRC_DEP:=
|
||||
|
||||
|
||||
NAME_OBJS = $(patsubst %.s, %.obj, $(patsubst %.asm, %.obj,\
|
||||
$(patsubst %.c, %.obj, $(NAME_SRC))))
|
||||
|
||||
|
||||
|
||||
all: $(NAME).dll
|
||||
|
||||
$(NAME).dll: $(NAME_OBJS) $(SRC_DEP) $(HFILES) atikms.lds Makefile
|
||||
ld -L$(LIBPATH) $(LDFLAGS) -T atikms.lds -o $@ $(NAME_OBJS) vsprintf.obj icompute.obj $(LIBS)
|
||||
|
||||
|
||||
%.obj : %.c $(HFILES) Makefile
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ -c $<
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user