mirror of
https://github.com/CTCaer/hekate.git
synced 2025-04-20 03:25:01 +00:00
Compare commits
853 commits
Author | SHA1 | Date | |
---|---|---|---|
|
3250b2e32a | ||
|
e3eee73318 | ||
|
81fb318f6b | ||
|
84f3f7d92a | ||
|
788ecb60a3 | ||
|
14413ae6bd | ||
|
1849ac6667 | ||
|
1bec721baf | ||
|
6fa844b031 | ||
|
d2fc6379c6 | ||
|
f15af01727 | ||
|
69acef4db3 | ||
|
cdc1012f50 | ||
|
63c4bdd7d9 | ||
|
0e23d0e0fd | ||
|
9463f8aa7d | ||
|
34f8692f5c | ||
|
9da5149394 | ||
|
75676a78ff | ||
|
66454b934c | ||
|
7b60c3d162 | ||
|
c422d63b64 | ||
|
0acdefb32a | ||
|
edf00d8e51 | ||
|
1a98e3a702 | ||
|
8bf3bee08b | ||
|
f2be59888b | ||
|
5c77601f7a | ||
|
9e239df39e | ||
|
b1bc6ebdd8 | ||
|
5c39d04ca2 | ||
|
85cd26e305 | ||
|
6c601ccaa5 | ||
|
0aea402632 | ||
|
280ebcc1e6 | ||
|
106a08f19c | ||
|
aacae78420 | ||
|
716cfbfbaf | ||
|
e47b6ec19b | ||
|
acb3997a7d | ||
|
4c5cc6d567 | ||
|
c321d3508c | ||
|
66303d0d47 | ||
|
80b3651d0a | ||
|
242debfe3e | ||
|
68408bbb79 | ||
|
cf954b451c | ||
|
75a4a8ba1d | ||
|
a37b5c7841 | ||
|
48334779a5 | ||
|
054c68f251 | ||
|
655209bedc | ||
|
85eb5489fe | ||
|
11262c2112 | ||
|
8b4f776c9d | ||
|
a34206df5b | ||
|
4a24fe0b35 | ||
|
14c482ddce | ||
|
8d49bc3c33 | ||
|
39c614a3ab | ||
|
7652d9cdb1 | ||
|
21d782587f | ||
|
48ef1826e9 | ||
|
4fef1890aa | ||
|
320b91a767 | ||
|
c5f6837c35 | ||
|
72f980d0f4 | ||
|
b3be7e7a41 | ||
|
26c6c6372d | ||
|
28eb3f4bcd | ||
|
bd55a3e756 | ||
|
146ff53a31 | ||
|
a96cac5964 | ||
|
b01cc2432f | ||
|
05db43a97c | ||
|
859811a154 | ||
|
0a6521ec26 | ||
|
6b54c4a477 | ||
|
e46f54d4e6 | ||
|
9d79af231e | ||
|
d933aa80f7 | ||
|
84c5439c70 | ||
|
ddd19661bd | ||
|
78cdb5575d | ||
|
8c44969afb | ||
|
7a74761da9 | ||
|
14706cef4e | ||
|
93296c2c38 | ||
|
b744f82942 | ||
|
c4567ab2b5 | ||
|
0544f9143f | ||
|
a070d2e394 | ||
|
927489d2da | ||
|
5453c593a3 | ||
|
ae29f359ee | ||
|
7af343dd6c | ||
|
547a3542ee | ||
|
4bc0a0591c | ||
|
1214ab0e02 | ||
|
985c513770 | ||
|
16eb6a3c44 | ||
|
ef1e328e11 | ||
|
856994e4f4 | ||
|
77782b974c | ||
|
38f4902e1d | ||
|
90b9f9f589 | ||
|
ec2e62236a | ||
|
2648a2655c | ||
|
62153fdfbb | ||
|
28960728f9 | ||
|
902ccede9a | ||
|
96efa7a002 | ||
|
d92906db5e | ||
|
e8d6516f43 | ||
|
a6727f6e32 | ||
|
35ea35f6ad | ||
|
9e1b2ee573 | ||
|
9cfe1d2162 | ||
|
cfbbafe72f | ||
|
5607fd18ea | ||
|
d71903abf2 | ||
|
547cfca0c9 | ||
|
dca350bfe9 | ||
|
06b7a38d47 | ||
|
9567ba19c8 | ||
|
c9ff5179f9 | ||
|
f764bf04b1 | ||
|
8b1486c74b | ||
|
471b99366d | ||
|
368ca21316 | ||
|
c021aef9b0 | ||
|
622f7124ac | ||
|
e846f4576e | ||
|
42c02e97e8 | ||
|
4b3014bc18 | ||
|
4effaab241 | ||
|
d687b53249 | ||
|
9e41aa7759 | ||
|
0100c11757 | ||
|
9ba7c44b89 | ||
|
cdf0f30b17 | ||
|
9a520d63a6 | ||
|
20e661fc01 | ||
|
e341cf39f2 | ||
|
3a4fa12f42 | ||
|
fb31cb2926 | ||
|
82925845e3 | ||
|
f126486266 | ||
|
25b7ffecd1 | ||
|
7d1600b85c | ||
|
b1e6661a7a | ||
|
83ac40c4b9 | ||
|
29d1e4a809 | ||
|
2ff2a5df2f | ||
|
4131ff12d7 | ||
|
5f8814311e | ||
|
9ea847578e | ||
|
f37ae083ae | ||
|
feb5b11f66 | ||
|
e96e74c72a | ||
|
6e6f5f8eed | ||
|
35c36908a1 | ||
|
6d69ef3cf6 | ||
|
abeafb9a67 | ||
|
be3297ae1f | ||
|
f05563579e | ||
|
644747230c | ||
|
05f4c42a2d | ||
|
1f30b8deb7 | ||
|
6c518435ec | ||
|
25e48472c8 | ||
|
bfc6069b2d | ||
|
38a792e564 | ||
|
8c5fdf52d4 | ||
|
4576ed81ef | ||
|
e9d2bdb124 | ||
|
b37430dc1d | ||
|
75543875e2 | ||
|
cc50ed2051 | ||
|
d1bae553ec | ||
|
30c320d6e7 | ||
|
eff27d92f2 | ||
|
3874840d77 | ||
|
74e252aaf2 | ||
|
c7333e710c | ||
|
dab5eb9aa0 | ||
|
92093ff08e | ||
|
2cc6cd45d9 | ||
|
a6ec41744b | ||
|
bb6e4deb4c | ||
|
1522f1ee92 | ||
|
41d3565353 | ||
|
e23d469f06 | ||
|
bd1733c4fa | ||
|
db214f2865 | ||
|
b584a3f53a | ||
|
7f98fb736a | ||
|
87c50732c0 | ||
|
504659a39b | ||
|
e47a819948 | ||
|
39abeb9a28 | ||
|
80a32304cb | ||
|
913cdee8e8 | ||
|
eff55ff378 | ||
|
09dfcfc57d | ||
|
239c48c790 | ||
|
2e1a773a08 | ||
|
d1ee0e35fd | ||
|
226b30b57c | ||
|
7fab13b76d | ||
|
d3d3768c8f | ||
|
7040f1ada2 | ||
|
697bde8667 | ||
|
03f11370c7 | ||
|
533fb08a1c | ||
|
c828539544 | ||
|
d1be18821d | ||
|
613fdf621d | ||
|
5b13e81141 | ||
|
ce137852b7 | ||
|
e84367e302 | ||
|
e5a22230b1 | ||
|
ce42e27f45 | ||
|
01a8f30925 | ||
|
d73a3fdd7c | ||
|
fdf0dcc636 | ||
|
976a02f8bc | ||
|
187b6d843e | ||
|
6de29094fe | ||
|
f2bdc3f47c | ||
|
09b1efe2a4 | ||
|
bb0a1fd0a2 | ||
|
1cc97ebc51 | ||
|
1e28320e5a | ||
|
0fe17cfb41 | ||
|
91393700ff | ||
|
cb964fe5d2 | ||
|
010b08d4c7 | ||
|
b5fcdad33f | ||
|
6061bb5213 | ||
|
221614212a | ||
|
5b94e8cf8a | ||
|
f291a5cfa7 | ||
|
7e397b3403 | ||
|
f35c5b0596 | ||
|
b142ca0f33 | ||
|
21da947c02 | ||
|
317abb2f4e | ||
|
d3567736c8 | ||
|
9187fa7a8c | ||
|
b9bc35a22e | ||
|
6e954f5cdf | ||
|
d7ad9b874b | ||
|
820e6d5a6e | ||
|
0215d16405 | ||
|
c0c0e34ef0 | ||
|
581ac8ec33 | ||
|
26bf148188 | ||
|
dc8f6beb8d | ||
|
25b181bf36 | ||
|
66e5e128f6 | ||
|
84822726cb | ||
|
b6e1e0d412 | ||
|
496737248c | ||
|
4f52e1f24a | ||
|
3f9c7a7da6 | ||
|
93ed4d0899 | ||
|
01afd2de56 | ||
|
d621d96af1 | ||
|
b674624ad0 | ||
|
191a0533d9 | ||
|
8502731fbd | ||
|
18f3a1b70c | ||
|
418f029d11 | ||
|
066efda4cd | ||
|
d8d15bde44 | ||
|
9d8ebc7e38 | ||
|
c2ee6be2f5 | ||
|
73a133556d | ||
|
7d3663616e | ||
|
e76aebabba | ||
|
bc0eea11f3 | ||
|
937ab52d14 | ||
|
e896d388ab | ||
|
ded959c449 | ||
|
a7fd83c793 | ||
|
dd380d4d47 | ||
|
795b4ad26e | ||
|
bb10b8aea3 | ||
|
811fa4c88b | ||
|
22462e4bf3 | ||
|
ca0263fa8c | ||
|
b1112e0949 | ||
|
3c3fcb29f9 | ||
|
8528e6a08a | ||
|
27ae312227 | ||
|
50811aacfa | ||
|
f4bf48e76a | ||
|
d258c82d52 | ||
|
7f32c6d211 | ||
|
2f7e841b50 | ||
|
29e32f09fb | ||
|
b123571c56 | ||
|
b7164a629f | ||
|
25be98b7e3 | ||
|
76a5facbc3 | ||
|
502fc1ed50 | ||
|
5e134ed54b | ||
|
4cfe5f241e | ||
|
9a222e0e49 | ||
|
298893f404 | ||
|
1ce5bb10f8 | ||
|
107fbd1d24 | ||
|
1edb6583ac | ||
|
5bdf323e5c | ||
|
d286ee4e9d | ||
|
17cdd5af0d | ||
|
26fa363ca4 | ||
|
2e8bfc1f56 | ||
|
07dafe8185 | ||
|
7f92f65c26 | ||
|
55e01ca735 | ||
|
a44a4881d4 | ||
|
c279fa2521 | ||
|
0f6f5f06c7 | ||
|
8600174d66 | ||
|
a6d7fa7fe1 | ||
|
c9405680f2 | ||
|
64dac28073 | ||
|
5193416658 | ||
|
9a98c1afb9 | ||
|
361aaf8629 | ||
|
080e3e2aa7 | ||
|
72abe60a3b | ||
|
ee682fdf24 | ||
|
42859a2373 | ||
|
22bdd0e0ff | ||
|
114abba815 | ||
|
ec8c04db8a | ||
|
4d7eb6a647 | ||
|
fd3cf1b7f8 | ||
|
47f0734ba0 | ||
|
5bb9a244ea | ||
|
05b5e4f297 | ||
|
4e15e034b8 | ||
|
ee3fc499cd | ||
|
f9e99212fc | ||
|
1666daf447 | ||
|
cfbfe403c6 | ||
|
47784faab2 | ||
|
a2a302b9d5 | ||
|
50dd458cfd | ||
|
2218ae228f | ||
|
20915dd661 | ||
|
0ba9b49074 | ||
|
1582ef3a29 | ||
|
0a367b114c | ||
|
f49aecad19 | ||
|
0b1bb521d8 | ||
|
2e989c2338 | ||
|
0e1eece04f | ||
|
2119401b5c | ||
|
c9ab6352f6 | ||
|
09ca75dd8c | ||
|
157464753f | ||
|
560f077196 | ||
|
4d823d5909 | ||
|
a1fde0d9b6 | ||
|
d0b22bf374 | ||
|
4da1d10553 | ||
|
f16159542c | ||
|
6257d20db9 | ||
|
227fe9b7ea | ||
|
24795891ec | ||
|
c86554e954 | ||
|
c0cc9c9f4f | ||
|
1bef259571 | ||
|
fe0bd89c4c | ||
|
f534d5e316 | ||
|
8d2fac60ea | ||
|
2ea595e98d | ||
|
7e7e86b713 | ||
|
a6d0bf54cd | ||
|
e455fe043f | ||
|
1a8075669d | ||
|
31c8292f23 | ||
|
414721a1ff | ||
|
9c1238f99d | ||
|
c0b16320cc | ||
|
e7866387cd | ||
|
6739f03893 | ||
|
0a9c71d5d6 | ||
|
833f060c7b | ||
|
9d889e2c3e | ||
|
efe6e2f206 | ||
|
5cdee01c05 | ||
|
6337b06212 | ||
|
f5fb0a1ee9 | ||
|
7cac7fe095 | ||
|
fefa7d9149 | ||
|
bfad719fcd | ||
|
4f2a6f16d3 | ||
|
f41d6be8d4 | ||
|
5392971c2c | ||
|
07695196cb | ||
|
8bbe403e41 | ||
|
d08fac5a08 | ||
|
197ce4c76f | ||
|
eaa25114ad | ||
|
0b2c2aa564 | ||
|
2aa251c44f | ||
|
c52c11e7bc | ||
|
ff5ee9758d | ||
|
a33663f759 | ||
|
44b429d5cd | ||
|
b891657fb6 | ||
|
801ebd3543 | ||
|
d259d6f6d6 | ||
|
70523e404f | ||
|
1499f958dd | ||
|
b787053c2d | ||
|
fe7fd6370e | ||
|
535ea95086 | ||
|
eba6b285ec | ||
|
e921d8f51c | ||
|
57c8fd1f8c | ||
|
d38ddad873 | ||
|
b0c0a86108 | ||
|
061e10152f | ||
|
b65b2d7f71 | ||
|
3369dcd110 | ||
|
677770bfee | ||
|
50886382bf | ||
|
2378bf2863 | ||
|
e5ddac5211 | ||
|
489e222aac | ||
|
16af97c79a | ||
|
bdb8f6d352 | ||
|
e2f6e925c4 | ||
|
258a343e21 | ||
|
f6c9e636d1 | ||
|
605f270f98 | ||
|
3fa01a1975 | ||
|
0e526bf9e8 | ||
|
c77c741c07 | ||
|
358896eb7d | ||
|
10205b17dd | ||
|
75b7d91abf | ||
|
369df25cd3 | ||
|
af22085172 | ||
|
38010ce65e | ||
|
8428ce1a2e | ||
|
bf00c79edb | ||
|
429074293a | ||
|
2c768db542 | ||
|
889317da58 | ||
|
e09710e3eb | ||
|
fb45804adf | ||
|
796207a41b | ||
|
1649d446cd | ||
|
7459214fed | ||
|
e9587a325c | ||
|
331f1926d1 | ||
|
87fe374b3b | ||
|
b56e788d12 | ||
|
abdf621ad5 | ||
|
9e613a7600 | ||
|
c2ff5dbd1c | ||
|
b9cdf5d697 | ||
|
b6384d5da5 | ||
|
7df76bff4a | ||
|
54b054c940 | ||
|
f31170bb51 | ||
|
f452d916c9 | ||
|
47d06d0e8a | ||
|
2aed1b3b83 | ||
|
12aac3a0fc | ||
|
833a115eb2 | ||
|
9f30c51bd1 | ||
|
62d68b33c3 | ||
|
c51877d588 | ||
|
471f3c50ea | ||
|
6d66bfc168 | ||
|
9163151dd0 | ||
|
334d89973f | ||
|
f7bf4af3ec | ||
|
ae394d9f37 | ||
|
c2869703af | ||
|
ebe7b5a603 | ||
|
ebf0db77ee | ||
|
81730c5f7e | ||
|
76d1b4e221 | ||
|
4a1cb1f2ea | ||
|
58a2094448 | ||
|
1b7b7ab7f5 | ||
|
37de367fef | ||
|
450d95e573 | ||
|
969a49edba | ||
|
9908eb8bb3 | ||
|
56dcbb2b23 | ||
|
b9f40fed7a | ||
|
6ae4904c8f | ||
|
dd2bb0f555 | ||
|
0b8cdaf0ea | ||
|
8f540b2543 | ||
|
f687c4f6da | ||
|
5c4e895c35 | ||
|
83c95d8a3b | ||
|
ff214f25c1 | ||
|
f818d094c5 | ||
|
69c312daac | ||
|
b7e59dfc28 | ||
|
c04d423f4b | ||
|
af1ece903b | ||
|
547c90a0a9 | ||
|
0fef90dc4c | ||
|
a76ad9838e | ||
|
499a9cf5f3 | ||
|
cfd6567f5d | ||
|
ee465b98af | ||
|
9aa55c2d76 | ||
|
83b895a062 | ||
|
ad4014f295 | ||
|
ce8d1eca91 | ||
|
73d38e1183 | ||
|
3f65a30b2e | ||
|
7c74391754 | ||
|
70ee61f0da | ||
|
b0b538f8f2 | ||
|
52bb6a96e5 | ||
|
6666dd4b46 | ||
|
4a13a1d190 | ||
|
2b7217242d | ||
|
ce16a08694 | ||
|
0ad42762e7 | ||
|
5f337bffd6 | ||
|
3fdb72ce37 | ||
|
9a80f8b4b5 | ||
|
c0c8fb263a | ||
|
ef5790cc2c | ||
|
7bb8b1da62 | ||
|
aee5861f65 | ||
|
2f1d1572f7 | ||
|
d52283f0c2 | ||
|
6be12f32e6 | ||
|
49f34581bb | ||
|
0a1db98210 | ||
|
17b0270eb5 | ||
|
39ce19e6f4 | ||
|
b18b5076b3 | ||
|
6ac9d79282 | ||
|
836530d4e3 | ||
|
3b2f438f69 | ||
|
781f377083 | ||
|
20c4d6dba6 | ||
|
192a936a31 | ||
|
23945ee12f | ||
|
8327de8e2e | ||
|
960f3b23e7 | ||
|
28167b7304 | ||
|
b08e36a7b0 | ||
|
943f675046 | ||
|
00110a8863 | ||
|
7ae4fd03c2 | ||
|
e071fe44b0 | ||
|
39d411dc68 | ||
|
82f90fae28 | ||
|
10e1f67dc5 | ||
|
10b479dc1c | ||
|
3dd12321f8 | ||
|
c1441a64c7 | ||
|
0e35e68fd5 | ||
|
853f10f774 | ||
|
4628ee6dc5 | ||
|
3bb46c6470 | ||
|
6a74f6ed04 | ||
|
d1c0d464dc | ||
|
6092994240 | ||
|
5a88f7bc06 | ||
|
06e7af150e | ||
|
864ec50a2d | ||
|
aa0a9da37b | ||
|
30a4861da6 | ||
|
5e6a7c486b | ||
|
1a9c6bf983 | ||
|
70504c295e | ||
|
5894062b93 | ||
|
a5cd962f99 | ||
|
01b6e645b3 | ||
|
db8c41cdaa | ||
|
b0fe84070f | ||
|
4d91d2baff | ||
|
c6fdb637ca | ||
|
bdd9e48606 | ||
|
25a7544010 | ||
|
821ad23341 | ||
|
981c986b3f | ||
|
09b3e47ac8 | ||
|
d2684f66a1 | ||
|
964381854e | ||
|
d8670fbd87 | ||
|
3c81ac91df | ||
|
147c82e0e2 | ||
|
339ce2d861 | ||
|
a7f0701cbf | ||
|
65b3b87c99 | ||
|
8d3700b76b | ||
|
d2595a00b6 | ||
|
c4bf129d5e | ||
|
503f4d4cd6 | ||
|
31d6c7d85d | ||
|
9a17ca2628 | ||
|
49bcaf3914 | ||
|
82d0346615 | ||
|
808da1bce0 | ||
|
6992ece762 | ||
|
734e70b755 | ||
|
681182540e | ||
|
9c29ee437a | ||
|
785baad5ea | ||
|
91b08f10fd | ||
|
c801ef8dda | ||
|
b47c01981f | ||
|
7e4c71748f | ||
|
a1910156d8 | ||
|
99d15eaac8 | ||
|
e31d6446db | ||
|
05ce867064 | ||
|
609a76045a | ||
|
000ea3096a | ||
|
0160df7fb9 | ||
|
05c989a1ce | ||
|
ebefd1c2d3 | ||
|
983d661da5 | ||
|
da08d00d21 | ||
|
6bd4c31965 | ||
|
af7bee2231 | ||
|
d61be73bca | ||
|
768b3ba2d9 | ||
|
0ff121284a | ||
|
bcc2512cb6 | ||
|
a2d18f0848 | ||
|
7fb10b0242 | ||
|
bcec028b0f | ||
|
8f9d52aa89 | ||
|
d368b93fdd | ||
|
d5322f384b | ||
|
03d027615c | ||
|
7fbab0122d | ||
|
f3f5687bc8 | ||
|
bbffcc20d7 | ||
|
197ed8c319 | ||
|
9363494c3f | ||
|
d8d32f7932 | ||
|
d575586d77 | ||
|
4326dcdc6c | ||
|
792a3511da | ||
|
9ba867f19e | ||
|
49943ee46f | ||
|
2a8c58af31 | ||
|
66cf88b967 | ||
|
f61e284ac0 | ||
|
9d69c9bd3f | ||
|
9258025eea | ||
|
063abb3e23 | ||
|
f5ec4a3a37 | ||
|
e9edcfeeb0 | ||
|
4b7e1f699d | ||
|
134f3dac52 | ||
|
1afb1a50c3 | ||
|
4914ce1d49 | ||
|
70a06a6cae | ||
|
5044f014bf | ||
|
7c72c9777a | ||
|
73df5e6743 | ||
|
9cf0b0f484 | ||
|
9541d1bbd3 | ||
|
3e15eb44ab | ||
|
bf89d9b841 | ||
|
d8995ee9c0 | ||
|
42f86cf82c | ||
|
a704679990 | ||
|
5876e1765d | ||
|
dcdf687a07 | ||
|
e94bd23d6f | ||
|
cd5b93feb1 | ||
|
f231173ebe | ||
|
561a96c62a | ||
|
57e6623d74 | ||
|
57623acc99 | ||
|
4f8d29d0b7 | ||
|
8eda2d805f | ||
|
432d4a4ffa | ||
|
539caf3d83 | ||
|
ce6926c36c | ||
|
8058d550ab | ||
|
9a21ff6976 | ||
|
1f4f41b6e6 | ||
|
a959196c2a | ||
|
3f22601022 | ||
|
a80a7ecba9 | ||
|
7c450f4a5f | ||
|
6316d3076d | ||
|
7181683d8e | ||
|
7d7134dd9e | ||
|
c29db97f73 | ||
|
05833bb38c | ||
|
253de81a6b | ||
|
21e6a0cf7e | ||
|
d0fefabad7 | ||
|
44db160ab1 | ||
|
cb633a8f32 | ||
|
66b7130641 | ||
|
80d9718770 | ||
|
dfbbca4c9f | ||
|
f4d08b2d9b | ||
|
588a834ae4 | ||
|
833dda7e7c | ||
|
6a4ab55930 | ||
|
d7ce2a81db | ||
|
4d90fa4830 | ||
|
501fdda138 | ||
|
678e8d34e3 | ||
|
07d1982abf | ||
|
fd05f83636 | ||
|
94e119fb51 | ||
|
c2ff4bf623 | ||
|
faf5651607 | ||
|
978e8344cf | ||
|
160d6eacc0 | ||
|
075d8e6393 | ||
|
28008ac7ac | ||
|
345d36287e | ||
|
edff6c551d | ||
|
d42a94f148 | ||
|
c01b8aa89c | ||
|
4958bd6a52 | ||
|
46038032a4 | ||
|
f66ddca100 | ||
|
6981c59de3 | ||
|
f21f13b15d | ||
|
ef5a01433d | ||
|
0e12d8545b | ||
|
9dbf745649 | ||
|
e8f73a42b8 | ||
|
dbe431095a | ||
|
513f77a2ad | ||
|
e8cf85bd65 | ||
|
be23d1fa15 | ||
|
4e7e5081a7 | ||
|
fff750e609 | ||
|
38ce46a158 | ||
|
7a27a7b3b5 | ||
|
c6ec175045 | ||
|
3b9ab66cf1 | ||
|
b6e458e97b | ||
|
c5152f6a9d | ||
|
e5689cfe57 | ||
|
f3f1d4d4f0 | ||
|
796b15a861 | ||
|
add351289a | ||
|
a4a056128a | ||
|
6e314933d9 | ||
|
a31bedda97 | ||
|
a25c82a8ce | ||
|
8ccc47dfa5 | ||
|
9de5a4ba66 | ||
|
84e437ae5b | ||
|
9e34c5995d | ||
|
497bbdf3cd | ||
|
8683a0ff58 | ||
|
874c801772 | ||
|
eea5463a5c | ||
|
af790aeaf8 | ||
|
a8a45b215a | ||
|
38f456a2ee | ||
|
a980eac647 | ||
|
ea83566fc9 | ||
|
0857d7ff0e | ||
|
48e98ab8c9 | ||
|
8cd438146d | ||
|
a80cc0ae2c | ||
|
2428736bfa | ||
|
a7bf8bf118 | ||
|
8038e1faa9 | ||
|
15a7e49dde | ||
|
8b30bd4b57 | ||
|
63d03303a2 | ||
|
0e40fef049 | ||
|
1a50425475 | ||
|
8fc5267110 | ||
|
f6a3b2c9ac | ||
|
7aa1e77642 | ||
|
2370ca0a44 | ||
|
abcf7f6f57 | ||
|
d1f0ea3de7 | ||
|
dbc8f4a4c2 | ||
|
c6c396ce2a | ||
|
74b91b0085 | ||
|
53c9ca8072 | ||
|
13e5216a4e | ||
|
147ccd3070 | ||
|
dc5c26e7c6 | ||
|
4914af1200 | ||
|
b57d26e99a | ||
|
f196b8bb0e | ||
|
7b460f7e56 | ||
|
9daa14abec | ||
|
bf8fd9a33b | ||
|
1f37b96359 | ||
|
46921aca22 | ||
|
41f96d4305 | ||
|
0959dc3a2d | ||
|
31baf3d19a | ||
|
f4696da0ef | ||
|
83ab79c51e | ||
|
745ac609d2 | ||
|
0f9aa51afe | ||
|
9fbb28e887 | ||
|
adf2045896 | ||
|
1a797bf93a | ||
|
1a9372b4ce | ||
|
87b91174ec | ||
|
26fff275ce | ||
|
53b44a525d | ||
|
8ce5d55eb8 | ||
|
afb749560a | ||
|
7a66e0298a | ||
|
e491a4cf57 | ||
|
b7789f1edb | ||
|
4949331f4c | ||
|
2c695e9a96 | ||
|
faaf801534 | ||
|
3fa775e3ad | ||
|
6663330de3 | ||
|
ed916360eb | ||
|
e4bc5c41ce | ||
|
d0d943c9c3 | ||
|
60b629e57f | ||
|
df80339060 | ||
|
cbbd427d3a | ||
|
dfcdb2e1e6 | ||
|
11ca6caf5f | ||
|
15afdf53e4 | ||
|
d15f958b48 | ||
|
5fd3bdede7 | ||
|
e2dd218f33 | ||
|
a85891ae00 | ||
|
2628044ba8 | ||
|
e620783a89 | ||
|
2fba9848ae | ||
|
52c65661d8 | ||
|
601c85c23e |
246 changed files with 27105 additions and 25311 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,4 +5,6 @@ output/*
|
|||
loader/payload_00.h
|
||||
loader/payload_01.h
|
||||
tools/bin2c/bin2c
|
||||
tools/bin2c/bin2c.exe
|
||||
tools/lz/lz77
|
||||
tools/lz/lz77.exe
|
||||
|
|
32
Makefile
32
Makefile
|
@ -25,16 +25,17 @@ VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir
|
|||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
start.o exception_handlers.o \
|
||||
main.o heap.o \
|
||||
gfx.o tui.o \
|
||||
fe_emmc_tools.o fe_info.o fe_tools.o \
|
||||
gfx.o logos.o tui.o \
|
||||
l4t.o fe_info.o fe_tools.o \
|
||||
)
|
||||
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
|
||||
pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o minerva.o \
|
||||
sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o nx_sd.o \
|
||||
bpmp.o ccplex.o clock.o di.o i2c.o irq.o timer.o \
|
||||
mc.o sdram.o minerva.o \
|
||||
gpio.o pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o \
|
||||
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
hw_init.o \
|
||||
)
|
||||
|
@ -47,7 +48,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||
|
||||
# Horizon.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o sept.o \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o \
|
||||
)
|
||||
|
||||
# Libraries.
|
||||
|
@ -63,8 +64,12 @@ FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"'
|
|||
################################################################################
|
||||
|
||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_VER_RL=$(BLVERSION_REL)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_VER_RL=$(NYXVERSION_REL)
|
||||
|
||||
# BDK defines.
|
||||
CUSTOMDEFINES += -DBDK_MALLOC_NO_DEFRAG -DBDK_MC_ENABLE_AHB_REDIRECT -DBDK_EMUMMC_ENABLE
|
||||
CUSTOMDEFINES += -DBDK_WATCHDOG_FIQ_ENABLE -DBDK_RESTART_BL_ON_WDT
|
||||
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
@ -73,8 +78,13 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
|||
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wsign-compare -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
#-fno-delete-null-pointer-checks
|
||||
#-Wstack-usage=byte-size -fstack-usage
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
|
@ -103,7 +113,7 @@ all: $(TARGET).bin $(LDRDIR)
|
|||
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean:
|
||||
clean: $(TOOLS)
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
|
|
197
README.md
197
README.md
|
@ -6,33 +6,61 @@
|
|||
Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many more.
|
||||
|
||||
|
||||
|
||||
- [Features](#features)
|
||||
- [Bootloader folders and files](#bootloader-folders-and-files)
|
||||
- [Bootloader configuration](#bootloader-configuration)
|
||||
* [hekate global Configuration keys/values](#hekate-global-configuration-keysvalues-when-entry-is-config)
|
||||
* [Boot entry key/value combinations](#boot-entry-keyvalue-combinations)
|
||||
* [Boot entry key/value combinations for Exosphère](#boot-entry-keyvalue-combinations-for-exosphère)
|
||||
* [Payload storage](#payload-storage)
|
||||
* [Nyx Configuration keys/values](#nyx-configuration-keysvalues-nyxini)
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **Fully Configurable and Graphical** with Touchscreen and Joycon input support
|
||||
- **Launcher Style, Background and Color Themes**
|
||||
- **HOS (Switch OS) Bootloader** -- For CFW Sys/Emu, OFW Sys and Stock Sys
|
||||
- **Android & Linux Bootloader**
|
||||
- **Payload Launcher**
|
||||
- **eMMC/emuMMC Backup/Restore Tools**
|
||||
- **SD Card Partition Manager** -- Prepares and formats SD Card for any combo of HOS (Sys/emuMMC), Android and Linux
|
||||
- **emuMMC Creation & Manager** -- Can also migrate and fix existing emuMMC
|
||||
- **Switch Android & Linux flasher**
|
||||
- **USB Mass Storage (UMS) for SD/eMMC/emuMMC** -- Converts Switch into a SD Card Reader
|
||||
- **USB Gamepad** -- Converts Switch with Joycon into a USB HID Gamepad
|
||||
- **Hardware and Peripherals info** (SoC, Fuses, RAM, Display, Touch, eMMC, SD, Battery, PSU, Charger)
|
||||
- **Many other tools** like Archive Bit Fixer, Touch Calibration, SD/eMMC Benchmark, AutoRCM enabler and more
|
||||
|
||||
|
||||
## Bootloader folders and files
|
||||
|
||||
| Folder/File | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------- |
|
||||
| bootloader | Main folder. |
|
||||
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
||||
| \|__ bootlogo.bmp | It is used if no `logopath` key is found. User provided. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries in `Launch` menu. |
|
||||
| \|__ nyx.ini | Nyx GUI configuration |
|
||||
| \|__ patches.ini | Add external patches. Can be skipped. A template can be found [here](./res/patches_template.ini) |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Auto updated. Can be skipped. |
|
||||
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. Normally for modchips. Auto updated and created at first boot. |
|
||||
| bootloader/ini/ | For individual inis. `More configs` menu. Autoboot is supported. |
|
||||
| bootloader/res/ | Nyx user resources. Icons and more. |
|
||||
| \|__ background.bmp | Nyx - custom background. |
|
||||
| \|__ background.bmp | Nyx - Custom background. User provided. |
|
||||
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
|
||||
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
|
||||
| \|__ icon_lakka.bmp | Nyx - Default icon for Lakka. |
|
||||
| bootloader/sys/ | For system modules. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. Important! |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. !Important! |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. Important! |
|
||||
| \|__ nyx.bin | Nyx - Our GUI. Important! |
|
||||
| \|__ res.pak | Nyx resources package. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. !Important! |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. !Important! |
|
||||
| \|__ res.pak | Nyx resources package. !Important! |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. !Important! |
|
||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||
| bootloader/libtools/ | Future reserved |
|
||||
| sept | Sept folder. This must always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. |
|
||||
| bootloader/payloads/ | For the `Payloads` menu. All CFW bootloaders, tools, Linux payloads are supported. Autoboot only supported by including them into an ini. |
|
||||
| bootloader/libtools/ | Reserved |
|
||||
|
||||
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
||||
|
||||
|
||||
## Bootloader configuration
|
||||
|
@ -43,16 +71,17 @@ The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is prese
|
|||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||
|
||||
|
||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
**You can find a template [Here](./res/hekate_ipl_template.ini)**
|
||||
|
||||
|
||||
### Global Configuration keys/values when boot entry is **config**:
|
||||
### hekate Global Configuration keys/values (when entry is *[config]*):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| autoboot_list=0 | 0: Read `autoboot` boot entry from hekate_ipl.ini, 1: Read from ini folder (ini files are ASCII ordered). |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. Max: 20s. |
|
||||
| noticker=0 | 0: Animated line is drawn during custom bootlogo, signifying time left to skip to menu. 1: Disable. |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
|
@ -60,53 +89,42 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
|||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
|
||||
### Nyx Global Configuration keys/values for (nyx.ini):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| themecolor=167 | Sets Nyx color of text highlights. |
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
| newpowersave=1 | 0: Timer based, 1: DRAM frequency based (Better). Use 0 if Nyx hangs. |
|
||||
|
||||
|
||||
### Boot entry key/value combinations:
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| warmboot={SD path} | Replaces the warmboot binary |
|
||||
| secmon={SD path} | Replaces the security monitor binary |
|
||||
| kernel={SD path} | Replaces the kernel binary |
|
||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. |
|
||||
| warmboot={FILE path} | Replaces the warmboot binary |
|
||||
| secmon={FILE path} | Replaces the security monitor binary |
|
||||
| kernel={FILE path} | Replaces the kernel binary |
|
||||
| kip1={FILE path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={FOLDER path}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={FILE path} | Takes an Atmosphere `package3` binary (formerly fusee-secondary.bin) and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere if enabled. |
|
||||
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
|
||||
| exofatal={SD path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. |
|
||||
| emupath={SD folder} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| exofatal={FILE path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or in one line with `,` as separator. If actual patch is not found, a warning will show up |
|
||||
| emupath={FOLDER path} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
|
||||
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
|
||||
| stock=1 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| id=idname | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
| logopath={SD path} | If no logopath, `bootloader/bootlogo.bmp` will be used if exists. If logopath exists, it will load the specified bitmap. |
|
||||
| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
|
||||
|
||||
|
||||
### Boot entry key/value Exosphère combinations:
|
||||
|
||||
| Config option | Description |
|
||||
| stock=1 | OFW via hekate bootloader. Disables unneeded kernel patching and CFW kips when running stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission). Doesn't work with Mesosphere as kernel. |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
||||
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| payload={FILE path} | Payload launching. Tools, Android/Linux, CFW bootloaders, etc. Any key above when used with that, doesn't get into account. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| l4t=1 | L4T Linux/Android native launching. |
|
||||
| boot_prefixes={FOLDER path} | L4T bootstack directory. |
|
||||
| ram_oc=0 | L4T RAM Overclocking. Check README_CONFIG.txt for more info. |
|
||||
| ram_oc_vdd2=1100 | L4T RAM VDD2 Voltage. Set VDD2 (T210B01) or VDD2/VDDQ (T210) voltage. 1050-1175. |
|
||||
| ram_oc_vddq=600 | L4T RAM VDDQ Voltage. Set VDDQ (T210B01). 550-650. |
|
||||
| uart_port=0 | Enables logging on serial port for L4T uboot/kernel. |
|
||||
| Additional keys | Each distro supports more keys. Check README_CONFIG.txt for more info. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| bootwait=3 | Overrides global bootwait from `[config]`. |
|
||||
| id=IDNAME | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||
| logopath={FILE path} | If it exists, it will load the specified bitmap. Otherwise `bootloader/bootlogo.bmp` will be used if exists |
|
||||
| icon={FILE path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise defaults will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
@ -114,8 +132,25 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
|||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be under `fss0` line.
|
||||
|
||||
|
||||
### Boot entry key/value combinations for Exosphère:
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
||||
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
|
||||
|
||||
|
||||
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
|
||||
|
||||
|
||||
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
|
@ -124,35 +159,55 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
|||
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit7: `sept run`. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`, 0: Force go to menu, else boot that entry. |
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`, bit7: `Run Dump pkg1/2`. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |
|
||||
|
||||
|
||||
If the main .ini is not found, it is created on the first hekate boot.
|
||||
### Nyx Configuration keys/values (nyx.ini):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| themebg=2d2d2d | Sets Nyx background color in HEX. EXPERIMENTAL. |
|
||||
| themecolor=167 | Sets Nyx color of text highlights. |
|
||||
| entries5col=0 | 1: Sets Launch entry columns from 4 to 5 per line. For a total of 10 entries. |
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| ------------------ | ------- The following options can only be edited in nyx.ini ------- |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
| jcforceright=0 | 1: Forces right joycon to be used as main mouse control. |
|
||||
| bpmpclock=1 | 0: Auto, 1: Fastest, 2: Faster, 3: Fast. Use 2 or 3 if Nyx hangs or some functions like UMS/Backup Verification fail. |
|
||||
|
||||
|
||||
```
|
||||
hekate (c) 2018, naehrwert, st4rk.
|
||||
(c) 2018-2020, CTCaer.
|
||||
(c) 2018-2024, CTCaer.
|
||||
|
||||
Nyx GUI (c) 2019-2020, CTCaer.
|
||||
Nyx GUI (c) 2019-2024, CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
||||
Open source and free packages used:
|
||||
- FatFs R0.13a, Copyright (c) 2017, ChaN
|
||||
- bcl-1.2.0, Copyright (c) 2003-2006, Marcus Geelnard
|
||||
- Atmosphère (Exosphere types/panic, prc id kernel patches),
|
||||
Copyright (c) 2018-2019, Atmosphère-NX
|
||||
- elfload, Copyright (c) 2014 Owen Shepherd, Copyright (c) 2018 M4xw
|
||||
- Littlev Graphics Library, Copyright (c) 2016 Gabor Kiss-Vamosi
|
||||
- Littlev Graphics Library,
|
||||
Copyright (c) 2016-2018 Gabor Kiss-Vamosi
|
||||
- FatFs R0.13c,
|
||||
Copyright (c) 2006-2018, ChaN
|
||||
Copyright (c) 2018-2022, CTCaer
|
||||
- bcl-1.2.0,
|
||||
Copyright (c) 2003-2006, Marcus Geelnard
|
||||
- blz,
|
||||
Copyright (c) 2018, SciresM
|
||||
- elfload,
|
||||
Copyright (c) 2014 Owen Shepherd,
|
||||
Copyright (c) 2018 M4xw
|
||||
|
||||
___
|
||||
.-' `'.
|
||||
|
|
|
@ -4,13 +4,16 @@ The bootlogo can be any size with a maximum of 720 x 1280.
|
|||
|
||||
When it's smaller than 720 x 1280, it is automatically centered and the background takes the color of the first pixel.
|
||||
|
||||
When saving a landscape bootlogo, it should be rotated 90 degrees counterclockwise.
|
||||
The process is to create a landscape bootlogo and then rotate it 90 degrees counterclockwise.
|
||||
|
||||
Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are not supported for performance reasons.
|
||||
|
||||
|
||||
## How to configure
|
||||
|
||||
If the custom logo option is enabled, it will try to load /bootlogo.bmp. If this is not found, the default hekate's logo will be used.
|
||||
If a boot entry specifies a custom logo path (`logopath=`), this one will be loaded.
|
||||
|
||||
If a boot entry specifies a custom logo path, this is one will be loaded. Again if this is not found, bootlogo.bmp will be loaded and if that fails, hekate's built-in will be used.
|
||||
If the above is not found or the format is not correct, it will try to load `bootloader/bootlogo.bmp`.
|
||||
If this is not found, the default hekate logo will be used.
|
||||
|
||||
(`bootloader/bootlogo.bmp` is basically like a global bootlogo.)
|
||||
|
|
16
Versions.inc
16
Versions.inc
|
@ -1,11 +1,11 @@
|
|||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 5
|
||||
BLVERSION_HOTFX := 1
|
||||
BLVERSION_RSVD := 0
|
||||
BLVERSION_MAJOR := 6
|
||||
BLVERSION_MINOR := 2
|
||||
BLVERSION_HOTFX := 2
|
||||
BLVERSION_REL := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 0
|
||||
NYXVERSION_MINOR := 9
|
||||
NYXVERSION_HOTFX := 7
|
||||
NYXVERSION_RSVD := 0
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 6
|
||||
NYXVERSION_HOTFX := 4
|
||||
NYXVERSION_REL := 0
|
||||
|
|
80
bdk/bdk.h
Normal file
80
bdk/bdk.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BDK_H
|
||||
#define BDK_H
|
||||
|
||||
#include <memory_map.h>
|
||||
|
||||
#include <display/di.h>
|
||||
#include <display/vic.h>
|
||||
#include <input/als.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
#include <mem/sdram.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <module.h>
|
||||
#include <power/bm92t36.h>
|
||||
#include <power/bq24193.h>
|
||||
#include <power/max17050.h>
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <power/max77812.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <rtc/max77620-rtc.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/tsec.h>
|
||||
#include <soc/actmon.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/kfuse.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/uart.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/nx_emmc_bis.h>
|
||||
#include <storage/ramdisk.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <thermal/fan.h>
|
||||
#include <thermal/tmp451.h>
|
||||
#include <usb/usbd.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/dirlist.h>
|
||||
#include <utils/ini.h>
|
||||
#include <utils/list.h>
|
||||
#include <utils/sprintf.h>
|
||||
#include <utils/types.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#endif
|
1047
bdk/display/di.c
Normal file
1047
bdk/display/di.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -24,6 +24,11 @@
|
|||
#define DSI_VIDEO_DISABLED 0
|
||||
#define DSI_VIDEO_ENABLED 1
|
||||
|
||||
#define WINDOW_A 0
|
||||
#define WINDOW_B 1
|
||||
#define WINDOW_C 2
|
||||
#define WINDOW_D 3
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
|
||||
|
@ -43,13 +48,17 @@
|
|||
|
||||
// DC_CMD non-shadowed command/sync registers.
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
#define SYNCPT_GENERAL_INDX(x) (((x) & 0xFF) << 0)
|
||||
#define SYNCPT_GENERAL_COND(x) (((x) & 0xFF) << 8)
|
||||
#define COND_REG_WR_SAFE 3
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_SOFT_RESET BIT(0)
|
||||
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xFF) << 0)
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
|
@ -72,19 +81,25 @@
|
|||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
||||
#define DC_CMD_INT_V_BLANK_INT BIT(2)
|
||||
#define DC_CMD_INT_POLARITY 0x3B
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX BIT(0)
|
||||
#define WRITE_MUX BIT(2)
|
||||
#define READ_MUX_ASSEMBLY 0x0
|
||||
#define WRITE_MUX_ASSEMBLY 0x0
|
||||
#define READ_MUX_ACTIVE BIT(0)
|
||||
#define WRITE_MUX_ACTIVE BIT(2)
|
||||
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define GENERAL_ACT_REQ BIT(0)
|
||||
#define WIN_ACT_REQ 1
|
||||
#define WIN_A_ACT_REQ BIT(1)
|
||||
#define WIN_B_ACT_REQ BIT(2)
|
||||
#define WIN_C_ACT_REQ BIT(3)
|
||||
#define WIN_D_ACT_REQ BIT(4)
|
||||
#define CURSOR_ACT_REQ BIT(7)
|
||||
#define GENERAL_UPDATE BIT(8)
|
||||
#define WIN_UPDATE 9
|
||||
#define WIN_A_UPDATE BIT(9)
|
||||
#define WIN_B_UPDATE BIT(10)
|
||||
#define WIN_C_UPDATE BIT(11)
|
||||
|
@ -93,12 +108,19 @@
|
|||
#define NC_HOST_TRIG BIT(24)
|
||||
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define WINDOW_SELECT 4
|
||||
#define WINDOW_A_SELECT BIT(4)
|
||||
#define WINDOW_B_SELECT BIT(5)
|
||||
#define WINDOW_C_SELECT BIT(6)
|
||||
#define WINDOW_D_SELECT BIT(7)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x43
|
||||
#define GENERAL_ACT_HCNTR_SEL BIT(0)
|
||||
#define WIN_A_ACT_HCNTR_SEL BIT(2)
|
||||
#define WIN_B_ACT_HCNTR_SEL BIT(4)
|
||||
#define WIN_C_ACT_HCNTR_SEL BIT(6)
|
||||
#define CURSOR_ACT_HCNTR_SEL BIT(7)
|
||||
#define WIN_D_ACT_HCNTR_SEL BIT(10)
|
||||
|
||||
// DC_D_WIN_DD window D instance of DC_WIN
|
||||
#define DC_D_WIN_DD_WIN_OPTIONS 0x80
|
||||
|
@ -124,6 +146,32 @@
|
|||
#define DC_COM_CRC_CONTROL 0x300
|
||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
|
||||
|
||||
// CMU registers.
|
||||
#define DC_COM_CMU_CSC_KRR 0x32A
|
||||
#define DC_COM_CMU_CSC_KGR 0x32B
|
||||
#define DC_COM_CMU_CSC_KBR 0x32C
|
||||
#define DC_COM_CMU_CSC_KRG 0x32D
|
||||
#define DC_COM_CMU_CSC_KGG 0x32E
|
||||
#define DC_COM_CMU_CSC_KBG 0x32F
|
||||
#define DC_COM_CMU_CSC_KRB 0x330
|
||||
#define DC_COM_CMU_CSC_KGB 0x331
|
||||
#define DC_COM_CMU_CSC_KBB 0x332
|
||||
#define DC_COM_CMU_LUT1 0x336
|
||||
#define LUT1_ADDR(x) ((x) & 0xFF)
|
||||
#define LUT1_DATA(x) (((x) & 0xFFF) << 16)
|
||||
#define LUT1_READ_DATA(x) (((x) >> 16) & 0xFFF)
|
||||
#define DC_COM_CMU_LUT2 0x337
|
||||
#define LUT2_ADDR(x) ((x) & 0x3FF)
|
||||
#define LUT2_DATA(x) (((x) & 0xFF) << 16)
|
||||
#define LUT2_READ_DATA(x) (((x) >> 16) & 0xFF)
|
||||
#define DC_COM_CMU_LUT1_READ 0x338
|
||||
#define LUT1_READ_ADDR(x) (((x) & 0xFF) << 8)
|
||||
#define LUT1_READ_EN BIT(0)
|
||||
#define DC_COM_CMU_LUT2_READ 0x339
|
||||
#define LUT2_READ_ADDR(x) (((x) & 0x3FF) << 8)
|
||||
#define LUT2_READ_EN BIT(0)
|
||||
|
||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||
|
||||
|
@ -139,15 +187,32 @@
|
|||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
|
||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||
#define VSYNC_H_POSITION(x) (((x) & 0x1FFF) << 0)
|
||||
|
||||
#define DC_DISP_REF_TO_SYNC 0x406
|
||||
#define H_REF_TO_SYNC(x) (((x) & 0x1FFF) << 0) // Min 0 pixel clock.
|
||||
#define V_REF_TO_SYNC(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
|
||||
|
||||
#define DC_DISP_SYNC_WIDTH 0x407
|
||||
#define H_SYNC_WIDTH(x) (((x) & 0x1FFF) << 0) // Min 1 pixel clock.
|
||||
#define V_SYNC_WIDTH(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
|
||||
|
||||
#define DC_DISP_BACK_PORCH 0x408
|
||||
#define H_BACK_PORCH(x) (((x) & 0x1FFF) << 0)
|
||||
#define V_BACK_PORCH(x) (((x) & 0x1FFF) << 16)
|
||||
|
||||
#define DC_DISP_ACTIVE 0x409
|
||||
#define H_DISP_ACTIVE(x) (((x) & 0x1FFF) << 0) // Min 16 pixel clock.
|
||||
#define V_DISP_ACTIVE(x) (((x) & 0x1FFF) << 16) // Min 16 line clock.
|
||||
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
#define H_FRONT_PORCH(x) (((x) & 0x1FFF) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1
|
||||
#define V_FRONT_PORCH(x) (((x) & 0x1FFF) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xFF)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||
|
@ -178,11 +243,7 @@
|
|||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
||||
|
||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
||||
#define DITHER_CONTROL_MASK (3 << 8)
|
||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
||||
#define BASE_COLOR_SIZE_MASK (0xF << 0)
|
||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
||||
|
@ -192,6 +253,13 @@
|
|||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||
#define DITHER_CONTROL_MASK (3 << 8)
|
||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||
#define DISP_COLOR_SWAP BIT(16)
|
||||
#define BLANK_COLOR_WHITE BIT(17)
|
||||
#define CMU_ENABLE BIT(20)
|
||||
|
||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||
#define SC0_H_QUALIFIER_NONE BIT(0)
|
||||
|
@ -213,6 +281,7 @@
|
|||
#define CURSOR_COLOR(r,g,b) (((r) & 0xFF) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16))
|
||||
|
||||
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
||||
#define DC_DISP_CURSOR_START_ADDR_NS 0x43F
|
||||
#define CURSOR_CLIPPING(w) ((w) << 28)
|
||||
#define CURSOR_CLIP_WIN_A 1
|
||||
#define CURSOR_CLIP_WIN_B 2
|
||||
|
@ -224,6 +293,7 @@
|
|||
#define DC_DISP_CURSOR_POSITION 0x440
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI_NS 0x4ED
|
||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||
#define CURSOR_BLEND_2BIT (0 << 24)
|
||||
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
|
||||
|
@ -239,32 +309,44 @@
|
|||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
|
||||
#define DC_WIN_CSC_YOF 0x611
|
||||
#define DC_WIN_CSC_KYRGB 0x612
|
||||
#define DC_WIN_CSC_KUR 0x613
|
||||
#define DC_WIN_CSC_KVR 0x614
|
||||
#define DC_WIN_CSC_KUG 0x615
|
||||
#define DC_WIN_CSC_KVG 0x616
|
||||
#define DC_WIN_CSC_KUB 0x617
|
||||
#define DC_WIN_CSC_KVB 0x618
|
||||
#define DC_WINC_COLOR_PALETTE 0x500
|
||||
#define COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off))
|
||||
#define COLOR_PALETTE_RGB(rgb) (byte_swap_32(rgb) >> 8)
|
||||
#define DC_WINC_PALETTE_COLOR_EXT 0x600
|
||||
|
||||
#define DC_WINC_H_FILTER_P(p) (0x601 + (p))
|
||||
#define DC_WINC_V_FILTER_P(p) (0x619 + (p))
|
||||
#define DC_WINC_H_FILTER_HI_P(p) (0x629 + (p))
|
||||
|
||||
#define DC_WINC_CSC_YOF 0x611
|
||||
#define DC_WINC_CSC_KYRGB 0x612
|
||||
#define DC_WINC_CSC_KUR 0x613
|
||||
#define DC_WINC_CSC_KVR 0x614
|
||||
#define DC_WINC_CSC_KUG 0x615
|
||||
#define DC_WINC_CSC_KVG 0x616
|
||||
#define DC_WINC_CSC_KUB 0x617
|
||||
#define DC_WINC_CSC_KVB 0x618
|
||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define H_FILTER_ENABLE BIT(8)
|
||||
#define V_FILTER_ENABLE BIT(10)
|
||||
#define COLOR_PALETTE_ENABLE BIT(16)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define DV_ENABLE BIT(20)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
#define H_FILTER_EXPAND BIT(31)
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define BUFFER_CONTROL_HOST 0
|
||||
#define BUFFER_CONTROL_VI 1
|
||||
#define BUFFER_CONTROL_EPP 2
|
||||
#define BUFFER_CONTROL_MPEGE 3
|
||||
#define BUFFER_CONTROL_SB2D 4
|
||||
|
||||
#define DC_WIN_COLOR_DEPTH 0x703
|
||||
|
@ -290,34 +372,55 @@
|
|||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||
#define WIN_COLOR_DEPTH_X1R5G5B5 0x1E
|
||||
#define WIN_COLOR_DEPTH_R5G5B5X1 0x1F
|
||||
#define WIN_COLOR_DEPTH_X1B5G5R5 0x20
|
||||
#define WIN_COLOR_DEPTH_B5G5R5X1 0x21
|
||||
#define WIN_COLOR_DEPTH_YCbCr444P 0x29
|
||||
#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A
|
||||
#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B
|
||||
#define WIN_COLOR_DEPTH_YCrCb422SP 0x2C
|
||||
#define WIN_COLOR_DEPTH_YCbCr422SP 0x2D
|
||||
#define WIN_COLOR_DEPTH_YUV444P 0x34
|
||||
#define WIN_COLOR_DEPTH_YVU420SP 0x35
|
||||
#define WIN_COLOR_DEPTH_YUV420SP 0x36
|
||||
#define WIN_COLOR_DEPTH_YVU422SP 0x37
|
||||
#define WIN_COLOR_DEPTH_YUV422SP 0x38
|
||||
#define WIN_COLOR_DEPTH_YVU444SP 0x3B
|
||||
#define WIN_COLOR_DEPTH_YUV444SP 0x3C
|
||||
|
||||
#define DC_WIN_POSITION 0x704
|
||||
#define H_POSITION(x) (((x) & 0xFfff) << 0)
|
||||
#define V_POSITION(x) (((x) & 0x1fff) << 16)
|
||||
#define H_POSITION(x) (((x) & 0xFFFF) << 0) // Support negative.
|
||||
#define V_POSITION(x) (((x) & 0xFFFF) << 16) // Support negative.
|
||||
|
||||
#define DC_WIN_SIZE 0x705
|
||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
#define H_SIZE(x) (((x) & 0x1FFF) << 0)
|
||||
#define V_SIZE(x) (((x) & 0x1FFF) << 16)
|
||||
|
||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7FFF) << 0)
|
||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1FFF) << 16)
|
||||
|
||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
||||
|
||||
#define DC_WIN_DDA_INC 0x709
|
||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
||||
#define H_DDA_INC(x) (((x) & 0xFFFF) << 0)
|
||||
#define V_DDA_INC(x) (((x) & 0xFFFF) << 16)
|
||||
|
||||
#define DC_WIN_LINE_STRIDE 0x70A
|
||||
#define LINE_STRIDE(x) (x)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xFFFF) << 16)
|
||||
|
||||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
#define DV_CTRL_R(r) (((r) & 7) << 16)
|
||||
#define DV_CTRL_G(g) (((g) & 7) << 8)
|
||||
#define DV_CTRL_B(b) (((b) & 7) << 0)
|
||||
|
||||
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
|
||||
#define WIN_K1(x) (((x) & 0xff) << 8)
|
||||
#define WIN_K2(x) (((x) & 0xff) << 16)
|
||||
#define WIN_BLEND_DEPTH(x) (((x) & 0xFF) << 0)
|
||||
#define WIN_K1(x) (((x) & 0xFF) << 8)
|
||||
#define WIN_K2(x) (((x) & 0xFF) << 16)
|
||||
#define WIN_BLEND_ENABLE (0 << 24)
|
||||
#define WIN_BLEND_BYPASS (1 << 24)
|
||||
|
||||
|
@ -348,8 +451,8 @@
|
|||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_K2 (3 << 12)
|
||||
|
||||
#define DC_WINBUF_BLEND_ALPHA_1BIT 0x719
|
||||
#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xff) << 0)
|
||||
#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xff) << 8)
|
||||
#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xFF) << 0)
|
||||
#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xFF) << 8)
|
||||
|
||||
/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
||||
#define DC_WINBUF_START_ADDR 0x800
|
||||
|
@ -361,6 +464,8 @@
|
|||
#define BLOCK (2 << 0)
|
||||
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
|
||||
|
||||
#define DC_WINBUF_MEMFETCH_CONTROL 0x82B
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
|
||||
|
@ -386,6 +491,7 @@
|
|||
#define DSI_HOST_CONTROL_FIFO_SEL BIT(4)
|
||||
#define DSI_HOST_CONTROL_HS BIT(5)
|
||||
#define DSI_HOST_CONTROL_RAW BIT(6)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_MASK (3 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
|
@ -433,30 +539,34 @@
|
|||
#define DSI_PKT_SEQ_5_LO 0x2D
|
||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define PKT0_LEN(x) (((x) & 0xFFFF) << 0)
|
||||
#define PKT1_LEN(x) (((x) & 0xFFFF) << 16)
|
||||
|
||||
#define DSI_PHY_TIMING_0 0x3C
|
||||
#define DSI_PHY_TIMING_1 0x3D
|
||||
#define DSI_PHY_TIMING_2 0x3E
|
||||
#define DSI_BTA_TIMING 0x3F
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xFFFF) << 0)
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xFFFF) << 16)
|
||||
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xFFFF) << 0)
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xFFFF) << 16)
|
||||
|
||||
#define DSI_TO_TALLY 0x46
|
||||
|
||||
#define DSI_PAD_CONTROL_0 0x4B
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xF) << 0)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xF) << 16)
|
||||
|
||||
#define DSI_PAD_CONTROL_CD 0x4C
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||
|
@ -547,17 +657,17 @@
|
|||
#define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID.
|
||||
#define MIPI_DCS_GET_NUM_ERRORS 0x05
|
||||
#define MIPI_DCS_GET_NUM_ERRORS 0x05 // 1 byte.
|
||||
#define MIPI_DCS_GET_RED_CHANNEL 0x06
|
||||
#define MIPI_DCS_GET_GREEN_CHANNEL 0x07
|
||||
#define MIPI_DCS_GET_BLUE_CHANNEL 0x08
|
||||
#define MIPI_DCS_GET_DISPLAY_STATUS 0x09
|
||||
#define MIPI_DCS_GET_POWER_MODE 0x0A
|
||||
#define MIPI_DCS_GET_ADDRESS_MODE 0x0B
|
||||
#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C
|
||||
#define MIPI_DCS_GET_DISPLAY_MODE 0x0D
|
||||
#define MIPI_DCS_GET_SIGNAL_MODE 0x0E
|
||||
#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F
|
||||
#define MIPI_DCS_GET_DISPLAY_STATUS 0x09 // 4 bytes.
|
||||
#define MIPI_DCS_GET_POWER_MODE 0x0A // 1 byte. 2: DISON, 3: NORON, 4: SLPOUT, 7: BSTON.
|
||||
#define MIPI_DCS_GET_ADDRESS_MODE 0x0B // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
|
||||
#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C // 1 byte. 4-6: DPI.
|
||||
#define MIPI_DCS_GET_DISPLAY_MODE 0x0D // 1 byte. 0-2: GCS, 3: ALLPOFF, 4: ALLPON, 5: INVON.
|
||||
#define MIPI_DCS_GET_SIGNAL_MODE 0x0E // 1 byte. 0: EODSI, 2: DEON, 3: PCLKON, 4: VSON, 5: HSON, 7: TEON.
|
||||
#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F // 1 byte. 6: FUNDT, 7: REGLD.
|
||||
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
|
||||
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
|
||||
#define MIPI_DCS_ENTER_PARTIAL_MODE 0x12
|
||||
|
@ -567,7 +677,7 @@
|
|||
#define MIPI_DCS_ALL_PIXELS_OFF 0x22
|
||||
#define MIPI_DCS_ALL_PIXELS_ON 0x23
|
||||
#define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer.
|
||||
#define MIPI_DCS_SET_GAMMA_CURVE 0x26
|
||||
#define MIPI_DCS_SET_GAMMA_CURVE 0x26 // 1 byte. 0-7: GC.
|
||||
#define MIPI_DCS_SET_DISPLAY_OFF 0x28
|
||||
#define MIPI_DCS_SET_DISPLAY_ON 0x29
|
||||
#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A
|
||||
|
@ -580,11 +690,11 @@
|
|||
#define MIPI_DCS_SET_SCROLL_AREA 0x33
|
||||
#define MIPI_DCS_SET_TEAR_OFF 0x34
|
||||
#define MIPI_DCS_SET_TEAR_ON 0x35
|
||||
#define MIPI_DCS_SET_ADDRESS_MODE 0x36
|
||||
#define MIPI_DCS_SET_ADDRESS_MODE 0x36 // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
|
||||
#define MIPI_DCS_SET_SCROLL_START 0x37
|
||||
#define MIPI_DCS_EXIT_IDLE_MODE 0x38
|
||||
#define MIPI_DCS_ENTER_IDLE_MODE 0x39
|
||||
#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A
|
||||
#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A // 1 byte. 4-6: DPI.
|
||||
#define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C
|
||||
#define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E
|
||||
#define MIPI_DCS_GET_3D_CONTROL 0x3F
|
||||
|
@ -593,26 +703,39 @@
|
|||
#define MIPI_DCS_GET_SCANLINE 0x45
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
|
||||
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
|
||||
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL.
|
||||
#define MIPI_DCS_GET_BRIGHTNESS 0x52
|
||||
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53
|
||||
#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54
|
||||
#define MIPI_DCS_SET_CABC_VALUE 0x55
|
||||
#define MIPI_DCS_GET_CABC_VALUE 0x56
|
||||
#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E
|
||||
#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F
|
||||
#define MIPI_DSI_AREA_COLOR_MODE 0x4C
|
||||
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_GET_BRIGHTNESS 0x52 // 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
|
||||
#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
|
||||
#define MIPI_DCS_SET_CABC_VALUE 0x55 // 1 byte. 0-32: C, 4-7: C.
|
||||
#define MIPI_DCS_GET_CABC_VALUE 0x56 // 1 byte. 0-32: C, 4-7: C.
|
||||
#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E // 1 byte. 0-7: CMB.
|
||||
#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F // 1 byte. 0-7: CMB.
|
||||
#define MIPI_DCS_GET_AUTO_BRI_DIAG_RES 0x68 // 1 byte. 6-7: D.
|
||||
#define MIPI_DCS_READ_DDB_START 0xA1
|
||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8
|
||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_UNK_A0 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
||||
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
#define MIPI_DCS_PRIV_SET_EXTC 0xB9
|
||||
#define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands.
|
||||
#define MIPI_DCS_PRIV_UNK_BD 0xBD
|
||||
#define MIPI_DCS_PRIV_UNK_D5 0xD5
|
||||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs PAGE 1. */
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID4 0x00
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID5 0x01
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID6 0x02
|
||||
|
||||
/*! MIPI DCS CMD Defines. */
|
||||
#define DCS_POWER_MODE_DISPLAY_ON BIT(2)
|
||||
|
@ -640,24 +763,57 @@
|
|||
#define DCS_GAMMA_CURVE_GC2_1_0 BIT(2)
|
||||
#define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more?
|
||||
|
||||
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
|
||||
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03
|
||||
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
|
||||
|
||||
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
||||
|
||||
#define PANEL_SM_BL_CANDELA_MAX 2047
|
||||
|
||||
/* Switch Panels:
|
||||
*
|
||||
* 6.2" panels for Icosa and Iowa skus:
|
||||
* 6.2" panels for Icosa and Iowa SKUs:
|
||||
* [10] 81 [26]: JDI LPM062M326A
|
||||
* [10] 96 [09]: JDI LAM062M109A
|
||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||
* [20] 96 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
|
||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||
* [30] 97 [0F]: AUO A062TAN02 (59.06A33.002) [From photo of assumed same panel]
|
||||
* [30] 98 [0F]: AUO A062TAN0? [UNCONFIRMED MODEL]
|
||||
* [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID]
|
||||
*
|
||||
* 5.5" panels for Hoag skus:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||
* [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID]
|
||||
* [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
|
||||
*
|
||||
* 5.5" panels for Hoag SKU:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) (6203B001P4000)
|
||||
* [20] 95 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 96 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [30] 93 [10]: AUO A055TAN01 (59.05A30.001)
|
||||
* [30] 94 [10]: AUO A055TAN02 (59.05A30.002)
|
||||
* [30] 95 [10]: AUO A055TAN03 (59.05A30.003)
|
||||
* [40] 94 [10]: Sharp LQ055T1SW10 (Rev P)
|
||||
*
|
||||
*
|
||||
* 7.0" OLED panels for Aula SKU:
|
||||
* [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5)
|
||||
*/
|
||||
|
||||
/* Display ID Decoding:
|
||||
|
@ -670,13 +826,13 @@
|
|||
* 10h: Japan Display Inc.
|
||||
* 20h: InnoLux Corporation
|
||||
* 30h: AU Optronics
|
||||
* 40h: Unknown1
|
||||
* 50h: Unknown2 (OLED? Samsung? LG?)
|
||||
* 40h: Sharp
|
||||
* 50h: Samsung
|
||||
*
|
||||
* Boards, Panel Size:
|
||||
* 0Fh: Icosa/Iowa, 6.2"
|
||||
* 10h: Hoag, 5.5"
|
||||
* 20h: Unknown, x.x"
|
||||
* 20h: Aula, 7.0"
|
||||
*/
|
||||
|
||||
enum
|
||||
|
@ -688,36 +844,60 @@ enum
|
|||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030,
|
||||
PANEL_V40_55_UNK = 0x1040
|
||||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||
PANEL_SAM_AMS699VC01 = 0x2050,
|
||||
|
||||
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
|
||||
PANEL_OEM_CLONE_6_2 = 0x0F83,
|
||||
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||
PANEL_OEM_CLONE_5_5 = 0x00B3,
|
||||
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||
PANEL_OEM_CLONE = 0x0000
|
||||
};
|
||||
|
||||
void display_init();
|
||||
void display_backlight_pwm_init();
|
||||
void display_end();
|
||||
|
||||
/*! Interrupt management. */
|
||||
void display_enable_interrupt(u32 intr);
|
||||
void display_disable_interrupt(u32 intr);
|
||||
void display_wait_interrupt(u32 intr);
|
||||
|
||||
/*! Get/Set Display panel ID. */
|
||||
u16 display_get_decoded_panel_id();
|
||||
void display_set_decoded_panel_id(u32 id);
|
||||
|
||||
/*! MIPI DCS register management */
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data);
|
||||
int display_dsi_vblank_read(u8 cmd, u32 len, void *data);
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data);
|
||||
void display_dsi_vblank_write(u8 cmd, u32 len, void *data);
|
||||
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Switches screen backlight ON/OFF. */
|
||||
void display_backlight(bool enable);
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
u32 display_get_backlight_brightness();
|
||||
|
||||
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
u32 *display_init_framebuffer_pitch();
|
||||
u32 *display_init_framebuffer_pitch_inv();
|
||||
u32 *display_init_framebuffer_block();
|
||||
u32 *display_init_framebuffer_log();
|
||||
void display_activate_console();
|
||||
void display_deactivate_console();
|
||||
void display_init_cursor(void *crs_fb, u32 size);
|
||||
void display_set_pos_cursor(u32 x, u32 y);
|
||||
void display_deinit_cursor();
|
||||
u32 *display_init_window_a_pitch();
|
||||
u32 *display_init_window_a_pitch_vic();
|
||||
u32 *display_init_window_a_pitch_inv();
|
||||
u32 *display_init_window_a_block();
|
||||
u32 *display_init_window_d_console();
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
void display_window_disable(u32 window);
|
||||
|
||||
void display_set_framebuffer(u32 window, void *fb);
|
||||
void display_move_framebuffer(u32 window, void *fb);
|
||||
|
||||
void display_window_d_console_enable();
|
||||
void display_window_d_console_disable();
|
||||
|
||||
void display_cursor_init(void *crs_fb, u32 size);
|
||||
void display_cursor_set_pos(u32 x, u32 y);
|
||||
void display_cursor_deinit();
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,122 +15,66 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
// Display A config.
|
||||
static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C.
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
|
||||
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
|
||||
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
|
||||
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | SYNCPT_VSYNC_INDX(9)},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||
|
||||
/* Setup Windows A/B/C */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
{DC_WINC_CSC_YOF, 0xF0},
|
||||
{DC_WINC_CSC_KYRGB, 0x12A},
|
||||
{DC_WINC_CSC_KUR, 0},
|
||||
{DC_WINC_CSC_KVR, 0x198},
|
||||
{DC_WINC_CSC_KUG, 0x39B},
|
||||
{DC_WINC_CSC_KVG, 0x32F},
|
||||
{DC_WINC_CSC_KUB, 0x204},
|
||||
{DC_WINC_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ}
|
||||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_dsi_init_config_part1[8] = {
|
||||
// DSI Init config.
|
||||
static const reg_cfg_t _di_dsi_seq_pkt_reset_config0[] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
{DSI_INT_MASK, 0},
|
||||
{DSI_INT_MASK, 0},
|
||||
{DSI_INIT_SEQ_DATA_0, 0},
|
||||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
||||
static const reg_cfg_t _di_dsi_seq_pkt_reset_config1[] = {
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
|
@ -146,7 +90,7 @@ static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
|||
{DSI_PKT_SEQ_5_HI, 0},
|
||||
{DSI_CONTROL, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
||||
static const reg_cfg_t _di_dsi_init_pads_t210b01[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
|
@ -155,55 +99,63 @@ static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
|||
{DSI_PAD_CONTROL_6_B01, 0},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part4[10] = {
|
||||
static const reg_cfg_t _di_dsi_init_config[] = {
|
||||
{DSI_PAD_CONTROL_CD, 0},
|
||||
{DSI_SOL_DELAY, 0x18},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_SOL_DELAY, 24},
|
||||
{DSI_MAX_THRESHOLD, 480},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0},
|
||||
|
||||
{DSI_PKT_LEN_0_1, 0},
|
||||
{DSI_PKT_LEN_2_3, 0},
|
||||
{DSI_PKT_LEN_4_5, 0},
|
||||
{DSI_PKT_LEN_6_7, 0},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part5[12] = {
|
||||
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
/* DSI timeout */
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
|
||||
|
||||
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Power up.
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part6[14] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
/* DSI timeout */
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI panel config.
|
||||
static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
// DSI panel JDI config.
|
||||
static const reg_cfg_t _di_dsi_panel_init_config_jdi[] = {
|
||||
{DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_WR_DATA, 0xBD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes.
|
||||
{DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8.
|
||||
|
@ -245,14 +197,20 @@ static const cfg_op_t _display_init_config_jdi[43] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//DSI packet config.
|
||||
static const cfg_op_t _display_dsi_packet_config[19] = {
|
||||
// DSI packet config.
|
||||
static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
/* DSI timeout */
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||
|
@ -261,66 +219,66 @@ static const cfg_op_t _display_dsi_packet_config[19] = {
|
|||
{DSI_PKT_SEQ_3_HI, 0x2CC},
|
||||
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
|
||||
{DSI_PKT_SEQ_5_HI, 0x2CC},
|
||||
{DSI_PKT_LEN_0_1, 0xCE0000},
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_PKT_LEN_0_1, PKT1_LEN(206) | PKT0_LEN(0)},
|
||||
{DSI_PKT_LEN_2_3, PKT1_LEN(2160) | PKT0_LEN(418)},
|
||||
{DSI_PKT_LEN_4_5, PKT1_LEN(0) | PKT0_LEN(400)},
|
||||
{DSI_PKT_LEN_6_7, PKT1_LEN(0) | PKT0_LEN(400)},
|
||||
{DSI_HOST_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI mode config.
|
||||
static const cfg_op_t _display_dsi_mode_config[10] = {
|
||||
// DSI mode config.
|
||||
static const reg_cfg_t _di_dsi_host_mode_config[] = {
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_SOL_DELAY, 6},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_MAX_THRESHOLD, 480},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_pad_cal_config[4] = {
|
||||
// MIPI CAL config.
|
||||
static const reg_cfg_t _di_mipi_pad_cal_config[] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
|
||||
// DSI pad config.
|
||||
static const reg_cfg_t _di_dsi_pad_cal_config_t210[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
static const reg_cfg_t _di_dsi_pad_cal_config_t210b01[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
{DSI_PAD_CONTROL_5_B01, 0x77777},
|
||||
{DSI_PAD_CONTROL_6_B01, 0x1111},
|
||||
{DSI_PAD_CONTROL_6_B01, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
|
||||
// MIPI CAL config.
|
||||
static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = {
|
||||
static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210b01[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
||||
static const reg_cfg_t _di_mipi_dsi_cal_unused_config[] = {
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||
|
@ -331,201 +289,88 @@ static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
|||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001}
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
|
||||
/* Set Display timings
|
||||
*
|
||||
* DC_DISP_REF_TO_SYNC:
|
||||
* V_REF_TO_SYNC - 1
|
||||
* H_REF_TO_SYNC - 0
|
||||
*
|
||||
* DC_DISP_SYNC_WIDTH:
|
||||
* V_SYNC_WIDTH - 1
|
||||
* H_SYNC_WIDTH - 72
|
||||
*
|
||||
* DC_DISP_BACK_PORCH:
|
||||
* V_BACK_PORCH - 9
|
||||
* H_BACK_PORCH - 72
|
||||
*
|
||||
* DC_DISP_ACTIVE:
|
||||
* V_DISP_ACTIVE - 1280
|
||||
* H_DISP_ACTIVE - 720
|
||||
*
|
||||
* DC_DISP_FRONT_PORCH:
|
||||
* V_FRONT_PORCH - 10
|
||||
* H_FRONT_PORCH - 136
|
||||
*/
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, 0x10000},
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
|
||||
// Display A enable config.
|
||||
static const reg_cfg_t _di_dc_video_enable_config[] = {
|
||||
/* Set panel timings */
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)},
|
||||
{DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)},
|
||||
{DC_DISP_SYNC_WIDTH, V_SYNC_WIDTH(1) | H_SYNC_WIDTH(72)},
|
||||
{DC_DISP_BACK_PORCH, V_BACK_PORCH(9) | H_BACK_PORCH(72)},
|
||||
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
|
||||
{DC_DISP_ACTIVE, V_DISP_ACTIVE(1280) | H_DISP_ACTIVE(720)},
|
||||
/* End of Display timings */
|
||||
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
|
||||
/* Start continuous display. */
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
|
||||
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)}, // 4: div3.
|
||||
};
|
||||
|
||||
////Display A config.
|
||||
static const cfg_op_t _display_video_disp_controller_disable_config[17] = {
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
// Display A disable config.
|
||||
static const reg_cfg_t _di_dc_video_disable_config[] = {
|
||||
{DC_CMD_INT_MASK, 0},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||
{DC_CMD_INT_ENABLE, 0},
|
||||
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
|
||||
|
||||
/* Stop display. */
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
// TODO: LCD panels should sleep for 40ms here.
|
||||
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
|
||||
// DSI deinit config.
|
||||
static const reg_cfg_t _di_dsi_timing_deinit_config[] = {
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
|
||||
/* DSI PHY timings */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
/* DSI timeout */
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_deinit_config_jdi[22] = {
|
||||
// DSI panel JDI deinit config.
|
||||
static const reg_cfg_t _di_dsi_panel_deinit_config_jdi[] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
|
@ -550,7 +395,8 @@ static const cfg_op_t _display_deinit_config_jdi[22] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
// DSI panel AUO deinit config.
|
||||
static const reg_cfg_t _di_dsi_panel_deinit_config_auo[] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
|
@ -591,156 +437,137 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_init_config_invert[3] = {
|
||||
/*
|
||||
static const reg_cfg_t _di_init_config_invert[] = {
|
||||
{DSI_WR_DATA, 0x239},
|
||||
{DSI_WR_DATA, 0x02C1}, // INV_EN.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
};
|
||||
*/
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
// Display A Window A one color config.
|
||||
static const reg_cfg_t _di_win_one_color[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
||||
};
|
||||
|
||||
//Display A config linear pitch.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
// Display A Window A linear pitch config.
|
||||
static const reg_cfg_t _di_winA_pitch[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config linear pitch inverse + Win D support.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
// Display A Window A linear pitch + Win D support config.
|
||||
static const reg_cfg_t _di_winA_pitch_vic[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
// Display A Window A linear pitch inverse + Win D support config.
|
||||
static const reg_cfg_t _di_winA_pitch_inv[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config block linear.
|
||||
static const cfg_op_t cfg_display_framebuffer_block[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
// Display A Window A block linear config.
|
||||
static const reg_cfg_t _di_winA_block[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC. Block in HOS: 0x13FF.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display D config.
|
||||
static const cfg_op_t cfg_display_framebuffer_log[20] = {
|
||||
// Display A Window D config.
|
||||
static const reg_cfg_t _di_winD_log[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)},
|
||||
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
|
||||
{DC_WIN_WIN_OPTIONS, 0}, // Enable window DD.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ},
|
||||
};
|
560
bdk/display/vic.c
Normal file
560
bdk/display/vic.c
Normal file
|
@ -0,0 +1,560 @@
|
|||
/*
|
||||
* VIC driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "vic.h"
|
||||
#include <mem/heap.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
/* VIC Private registers */
|
||||
#define PVIC_FALCON_PA_OFFSET 0x1000
|
||||
#define PVIC_FALCON_ADDR 0x10AC
|
||||
#define PVIC_FALCON_IDLESTATE 0x104C
|
||||
|
||||
/* VIC Control and Status registers. */
|
||||
/* Fetch Control registers. */
|
||||
#define VIC_FC_COMPOSE 0x10000
|
||||
#define COMPOSE_START BIT(0)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04
|
||||
#define SLOT_ENABLE BIT(0)
|
||||
#define FIELD_CURRENT_ENABLE BIT(8)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C
|
||||
#define CACHE_WIDTH(n) ((n) << 16)
|
||||
#define CACHE_WIDTH_16BX16 0 // Block Linear.
|
||||
#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear.
|
||||
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch.
|
||||
#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch.
|
||||
#define OUTPUT_FLIP_X BIT(20)
|
||||
#define OUTPUT_FLIP_Y BIT(21)
|
||||
#define OUTPUT_TRANSPOSE BIT(22)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34
|
||||
#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38
|
||||
#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C
|
||||
#define VIC_FC_SLOT_MAP 0x10C00
|
||||
|
||||
#define VIC_FC_FCE_CTRL 0x11000
|
||||
#define START_TRIGGER BIT(0)
|
||||
#define HALT_TRIGGER BIT(1)
|
||||
#define CLEAR_ERROR BIT(8)
|
||||
|
||||
#define VIC_FC_FCE_UCODE_ADDR 0x11200
|
||||
#define VIC_FC_FCE_UCODE_INST 0x11300
|
||||
|
||||
/* Surface List registers. */
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300
|
||||
#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400
|
||||
#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600
|
||||
|
||||
/* Surface Cache registers. */
|
||||
#define VIC_SC_PRAMBASE 0x14000
|
||||
#define VIC_SC_PRAMSIZE 0x14100
|
||||
#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100)
|
||||
|
||||
/* Blending Output registers. */
|
||||
#define VIC_BL_TARGET_BASADR 0x22000
|
||||
#define VIC_BL_CONFIG 0x22800
|
||||
#define SUBPARTITION_MODE BIT(0)
|
||||
#define PROCESS_CFG_STRUCT_TRIGGER BIT(2)
|
||||
#define SLOTMASK(n) ((n) << 8)
|
||||
|
||||
#define VIC_BL_CFG_STRUCT_CFG0 0x22C00
|
||||
#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04
|
||||
#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08
|
||||
#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C
|
||||
#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10
|
||||
#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14
|
||||
|
||||
// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0.
|
||||
#define BLK_KIND(n) ((n) << 8)
|
||||
#define BLK_KIND_PITCH 0
|
||||
#define BLK_KIND_GENERIC_16BX2 1
|
||||
#define BLK_HEIGHT(n) ((n) << 12)
|
||||
#define BLK_HEIGHT_ONE_GOB 0
|
||||
#define BLK_HEIGHT_SIXTEEN_GOBS 4
|
||||
|
||||
// Generic size macros.
|
||||
#define SIZE_WIDTH(n) (((n) - 1) << 0)
|
||||
#define SIZE_HEIGHT(n) (((n) - 1) << 16)
|
||||
#define RECT_LEFT(n) ((n) << 0)
|
||||
#define RECT_RIGHT(n) (((n) - 1) << 16)
|
||||
#define RECT_TOP(n) ((n) << 0)
|
||||
#define RECT_BOTTOM(n) (((n) - 1) << 16)
|
||||
|
||||
#define FORMAT_PROGRESSIVE 0
|
||||
#define SOFT_CLAMP_MIN 0
|
||||
#define SOFT_CLAMP_MAX 0x3FFu
|
||||
#define ALPHA_1_0 0x3FFu
|
||||
|
||||
typedef struct _OutputConfig {
|
||||
u64 AlphaFillMode:3;
|
||||
u64 AlphaFillSlot:3;
|
||||
u64 BackgroundAlpha:10;
|
||||
u64 BackgroundR:10;
|
||||
u64 BackgroundG:10;
|
||||
u64 BackgroundB:10;
|
||||
u64 RegammaMode:2;
|
||||
u64 OutputFlipX:1;
|
||||
u64 OutputFlipY:1;
|
||||
u64 OutputTranspose:1;
|
||||
u64 rsvd1:1;
|
||||
u64 rsvd2:12;
|
||||
u64 TargetRectLeft:14;
|
||||
u64 rsvd3:2;
|
||||
u64 TargetRectRight:14;
|
||||
u64 rsvd4:2;
|
||||
u64 TargetRectTop:14;
|
||||
u64 rsvd5:2;
|
||||
u64 TargetRectBottom:14;
|
||||
u64 rsvd6:2;
|
||||
} OutputConfig;
|
||||
|
||||
typedef struct _OutputSurfaceConfig {
|
||||
u64 OutPixelFormat:7;
|
||||
u64 OutChromaLocHoriz:2;
|
||||
u64 OutChromaLocVert:2;
|
||||
u64 OutBlkKind:4;
|
||||
u64 OutBlkHeight:4;
|
||||
u64 rsvd0:3;
|
||||
u64 rsvd1:10;
|
||||
u64 OutSurfaceWidth:14;
|
||||
u64 OutSurfaceHeight:14;
|
||||
u64 rsvd2:4;
|
||||
u64 OutLumaWidth:14;
|
||||
u64 OutLumaHeight:14;
|
||||
u64 rsvd3:4;
|
||||
u64 OutChromaWidth:14;
|
||||
u64 OutChromaHeight:14;
|
||||
u64 rsvd4:4;
|
||||
} OutputSurfaceConfig;
|
||||
|
||||
typedef struct _SlotConfig {
|
||||
u64 SlotEnable:1;
|
||||
u64 DeNoise:1;
|
||||
u64 AdvancedDenoise:1;
|
||||
u64 CadenceDetect:1;
|
||||
u64 MotionMap:1;
|
||||
u64 MMapCombine:1;
|
||||
u64 IsEven:1;
|
||||
u64 ChromaEven:1;
|
||||
u64 CurrentFieldEnable:1;
|
||||
u64 PrevFieldEnable:1;
|
||||
u64 NextFieldEnable:1;
|
||||
u64 NextNrFieldEnable:1;
|
||||
u64 CurMotionFieldEnable:1;
|
||||
u64 PrevMotionFieldEnable:1;
|
||||
u64 PpMotionFieldEnable:1;
|
||||
u64 CombMotionFieldEnable:1;
|
||||
u64 FrameFormat:4;
|
||||
u64 FilterLengthY:2;
|
||||
u64 FilterLengthX:2;
|
||||
u64 Panoramic:12;
|
||||
u64 rsvd1:22;
|
||||
u64 DetailFltClamp:6;
|
||||
u64 FilterNoise:10;
|
||||
u64 FilterDetail:10;
|
||||
u64 ChromaNoise:10;
|
||||
u64 ChromaDetail:10;
|
||||
u64 DeinterlaceMode:4;
|
||||
u64 MotionAccumWeight:3;
|
||||
u64 NoiseIir:11;
|
||||
u64 LightLevel:4;
|
||||
u64 rsvd4:2;
|
||||
u64 SoftClampLow:10;
|
||||
u64 SoftClampHigh:10;
|
||||
u64 rsvd5:3;
|
||||
u64 rsvd6:9;
|
||||
u64 PlanarAlpha:10;
|
||||
u64 ConstantAlpha:1;
|
||||
u64 StereoInterleave:3;
|
||||
u64 ClipEnabled:1;
|
||||
u64 ClearRectMask:8;
|
||||
u64 DegammaMode:2;
|
||||
u64 rsvd7:1;
|
||||
u64 DecompressEnable:1;
|
||||
u64 rsvd9:5;
|
||||
u64 DecompressCtbCount:8;
|
||||
u64 DecompressZbcColor:32;
|
||||
u64 rsvd12:24;
|
||||
u64 SourceRectLeft:30;
|
||||
u64 rsvd14:2;
|
||||
u64 SourceRectRight:30;
|
||||
u64 rsvd15:2;
|
||||
u64 SourceRectTop:30;
|
||||
u64 rsvd16:2;
|
||||
u64 SourceRectBottom:30;
|
||||
u64 rsvd17:2;
|
||||
u64 DestRectLeft:14;
|
||||
u64 rsvd18:2;
|
||||
u64 DestRectRight:14;
|
||||
u64 rsvd19:2;
|
||||
u64 DestRectTop:14;
|
||||
u64 rsvd20:2;
|
||||
u64 DestRectBottom:14;
|
||||
u64 rsvd21:2;
|
||||
u64 rsvd22:32;
|
||||
u64 rsvd23:32;
|
||||
} SlotConfig;
|
||||
|
||||
typedef struct _SlotSurfaceConfig {
|
||||
u64 SlotPixelFormat:7;
|
||||
u64 SlotChromaLocHoriz:2;
|
||||
u64 SlotChromaLocVert:2;
|
||||
u64 SlotBlkKind:4;
|
||||
u64 SlotBlkHeight:4;
|
||||
u64 SlotCacheWidth:3;
|
||||
u64 rsvd0:10;
|
||||
u64 SlotSurfaceWidth:14;
|
||||
u64 SlotSurfaceHeight:14;
|
||||
u64 rsvd1:4;
|
||||
u64 SlotLumaWidth:14;
|
||||
u64 SlotLumaHeight:14;
|
||||
u64 rsvd2:4;
|
||||
u64 SlotChromaWidth:14;
|
||||
u64 SlotChromaHeight:14;
|
||||
u64 rsvd3:4;
|
||||
} SlotSurfaceConfig;
|
||||
|
||||
typedef struct _SlotStruct {
|
||||
SlotConfig slot_cfg;
|
||||
SlotSurfaceConfig slot_sfc_cfg;
|
||||
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 lumaKeyStruct[0x10];
|
||||
u8 colorMatrixStruct[0x20];
|
||||
u8 gamutMatrixStruct[0x20];
|
||||
u8 blendingSlotStruct[0x10];
|
||||
} SlotStruct;
|
||||
|
||||
typedef struct _vic_config_t {
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 pipeConfig[0x10];
|
||||
|
||||
OutputConfig out_cfg;
|
||||
OutputSurfaceConfig out_sfc_cfg;
|
||||
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 out_color_matrix[0x20];
|
||||
u8 clear_rect[0x10 * 4];
|
||||
|
||||
SlotStruct slots[8];
|
||||
} vic_config_t;
|
||||
|
||||
// VIC Fetch Control Engine microcode. Dumped from L4T r33.
|
||||
u8 vic_fce_ucode[] = {
|
||||
0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00,
|
||||
0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00,
|
||||
0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00,
|
||||
0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00,
|
||||
0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00,
|
||||
0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
||||
0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00,
|
||||
0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00,
|
||||
0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00,
|
||||
0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00,
|
||||
0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00,
|
||||
0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00,
|
||||
0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00,
|
||||
0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00,
|
||||
0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00,
|
||||
0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00,
|
||||
0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00,
|
||||
0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00,
|
||||
0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00,
|
||||
0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00,
|
||||
0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00,
|
||||
0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00,
|
||||
0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00,
|
||||
0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00,
|
||||
0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00,
|
||||
0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00,
|
||||
0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00,
|
||||
0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00,
|
||||
0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00,
|
||||
0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00,
|
||||
0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00,
|
||||
0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00,
|
||||
0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00,
|
||||
0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00,
|
||||
0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
||||
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
||||
0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00,
|
||||
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00,
|
||||
0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00,
|
||||
0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00,
|
||||
0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
||||
0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00,
|
||||
0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00,
|
||||
0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00,
|
||||
0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00,
|
||||
0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
||||
0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00,
|
||||
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00,
|
||||
0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
||||
0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00,
|
||||
0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00,
|
||||
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00,
|
||||
0x6F, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0};
|
||||
|
||||
u32 _vic_read_priv(u32 addr)
|
||||
{
|
||||
u32 addr_lsb = addr & 0xFF;
|
||||
|
||||
// Set address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
||||
|
||||
// Set address.
|
||||
u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6));
|
||||
|
||||
// Unset address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void _vic_write_priv(u32 addr, u32 data)
|
||||
{
|
||||
u32 addr_lsb = addr & 0xFF;
|
||||
|
||||
// Set address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
||||
|
||||
// Set address.
|
||||
VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data;
|
||||
|
||||
// Unset address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = 0;
|
||||
}
|
||||
|
||||
static int _vic_wait_idle()
|
||||
{
|
||||
u32 timeout_count = 15000; // 150ms.
|
||||
|
||||
while (VIC(PVIC_FALCON_IDLESTATE))
|
||||
{
|
||||
usleep(10);
|
||||
|
||||
timeout_count--;
|
||||
if (!timeout_count)
|
||||
return -1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vic_set_surface(const vic_surface_t *sfc)
|
||||
{
|
||||
u32 flip_x = 0;
|
||||
u32 flip_y = 0;
|
||||
u32 swap_xy = 0;
|
||||
u32 const_alpha = 0;
|
||||
|
||||
u32 width = sfc->width;
|
||||
u32 height = sfc->height;
|
||||
u32 pix_fmt = sfc->pix_fmt;
|
||||
u32 src_buf = sfc->src_buf;
|
||||
u32 dst_buf = sfc->dst_buf;
|
||||
|
||||
// Get format alpha type.
|
||||
switch (sfc->pix_fmt)
|
||||
{
|
||||
case VIC_PIX_FORMAT_L8:
|
||||
case VIC_PIX_FORMAT_X1B5G5R5:
|
||||
case VIC_PIX_FORMAT_B5G5R5X1:
|
||||
case VIC_PIX_FORMAT_X8B8G8R8:
|
||||
case VIC_PIX_FORMAT_X8R8G8B8:
|
||||
case VIC_PIX_FORMAT_B8G8R8X8:
|
||||
case VIC_PIX_FORMAT_R8G8B8X8:
|
||||
const_alpha = 1;
|
||||
break;
|
||||
|
||||
case VIC_PIX_FORMAT_A8B8G8R8:
|
||||
case VIC_PIX_FORMAT_A8R8G8B8:
|
||||
case VIC_PIX_FORMAT_B8G8R8A8:
|
||||
case VIC_PIX_FORMAT_R8G8B8A8:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Get rotation parameters.
|
||||
switch (sfc->rotation)
|
||||
{
|
||||
case VIC_ROTATION_90:
|
||||
swap_xy = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_180:
|
||||
flip_x = 1;
|
||||
flip_y = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_270:
|
||||
flip_x = 1;
|
||||
swap_xy = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set output surface format.
|
||||
vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt;
|
||||
vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH;
|
||||
vic_cfg.out_sfc_cfg.OutBlkHeight = 0;
|
||||
|
||||
// Set output rotation/flip.
|
||||
vic_cfg.out_cfg.OutputFlipX = flip_x;
|
||||
vic_cfg.out_cfg.OutputFlipY = flip_y;
|
||||
vic_cfg.out_cfg.OutputTranspose = swap_xy;
|
||||
|
||||
// Set output surface resolution.
|
||||
vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1;
|
||||
vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1;
|
||||
vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1;
|
||||
vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1;
|
||||
|
||||
// Set output destination rectangle. Anything outside will not be touched at output buffer.
|
||||
vic_cfg.out_cfg.TargetRectLeft = 0;
|
||||
vic_cfg.out_cfg.TargetRectRight = width - 1;
|
||||
vic_cfg.out_cfg.TargetRectTop = 0;
|
||||
vic_cfg.out_cfg.TargetRectBottom = height - 1;
|
||||
|
||||
// Initialize slot parameters.
|
||||
vic_cfg.slots[0].slot_cfg.SlotEnable = 1;
|
||||
vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN;
|
||||
vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX;
|
||||
vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0;
|
||||
vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha;
|
||||
vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE;
|
||||
|
||||
// Set input source rectangle.
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectTop = 0;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16;
|
||||
|
||||
// Set input destination rectangle.
|
||||
vic_cfg.slots[0].slot_cfg.DestRectLeft = 0;
|
||||
vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1);
|
||||
vic_cfg.slots[0].slot_cfg.DestRectTop = 0;
|
||||
vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1);
|
||||
|
||||
// Set input surface format.
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4;
|
||||
|
||||
// Set input surface resolution.
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1;
|
||||
|
||||
// Flush data.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
// Set parameters base and size. Causes a parse by surface cache.
|
||||
_vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8);
|
||||
_vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
|
||||
// Set slot mapping.
|
||||
_vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
|
||||
|
||||
// Set input surface buffer.
|
||||
_vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8);
|
||||
|
||||
// Set output surface buffer.
|
||||
_vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8);
|
||||
|
||||
// Set blending config and push changes to surface cache.
|
||||
_vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
}
|
||||
|
||||
int vic_compose()
|
||||
{
|
||||
// Wait for surface cache to get ready. Otherwise VIC will hang.
|
||||
int res = _vic_wait_idle();
|
||||
|
||||
// Start composition of a single frame.
|
||||
_vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int vic_init()
|
||||
{
|
||||
clock_enable_vic();
|
||||
|
||||
// Load Fetch Control Engine microcode.
|
||||
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
||||
{
|
||||
_vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32)));
|
||||
_vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]);
|
||||
}
|
||||
|
||||
// Start Fetch Control Engine.
|
||||
_vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
|
||||
|
||||
return _vic_wait_idle();
|
||||
}
|
||||
|
||||
void vic_end()
|
||||
{
|
||||
clock_disable_vic();
|
||||
}
|
66
bdk/display/vic.h
Normal file
66
bdk/display/vic.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* VIC driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _VIC_H_
|
||||
#define _VIC_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define VIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
|
||||
|
||||
typedef enum _vic_rotation_t
|
||||
{
|
||||
VIC_ROTATION_0 = 0,
|
||||
VIC_ROTATION_90 = 1,
|
||||
VIC_ROTATION_180 = 2,
|
||||
VIC_ROTATION_270 = 3,
|
||||
} vic_rotation_t;
|
||||
|
||||
typedef enum _vic_pix_format_t
|
||||
{
|
||||
VIC_PIX_FORMAT_L8 = 1, // 8-bit LUT.
|
||||
VIC_PIX_FORMAT_X1B5G5R5 = 21, // 16-bit XBGR.
|
||||
VIC_PIX_FORMAT_B5G5R5X1 = 23, // 16-bit BGRX.
|
||||
|
||||
VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
|
||||
VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
|
||||
VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
|
||||
VIC_PIX_FORMAT_R8G8B8A8 = 34, // 32-bit RGBA.
|
||||
|
||||
VIC_PIX_FORMAT_X8B8G8R8 = 35, // 32-bit XBGR.
|
||||
VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
|
||||
VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
|
||||
VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
|
||||
} vic_pix_format_t;
|
||||
|
||||
typedef struct _vic_surface_t
|
||||
{
|
||||
u32 src_buf;
|
||||
u32 dst_buf;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 pix_fmt;
|
||||
u32 rotation;
|
||||
} vic_surface_t;
|
||||
|
||||
void vic_set_surface(const vic_surface_t *sfc);
|
||||
int vic_compose();
|
||||
int vic_init();
|
||||
void vic_end();
|
||||
|
||||
#endif
|
|
@ -97,6 +97,10 @@ _irq_setup:
|
|||
MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x40040000
|
||||
|
||||
/* Setup FIQ stack pointer */
|
||||
MSR CPSR, #(MODE_FIQ | IRQ | FIQ) /* FIQ mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x40040000
|
||||
|
||||
/* Setup SYS stack pointer */
|
||||
MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
|
||||
|
@ -111,7 +115,9 @@ _irq_setup:
|
|||
B ipl_main
|
||||
B .
|
||||
|
||||
_reset:
|
||||
.globl excp_reset
|
||||
.type excp_reset, %function
|
||||
excp_reset:
|
||||
LDR R0, =EXCP_EN_ADDR
|
||||
LDR R1, =0x30505645 /* EVP0 */
|
||||
STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
|
||||
|
@ -129,25 +135,25 @@ _reset_handler:
|
|||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x545352 /* RST */
|
||||
STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_undefined_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x464455 /* UDF */
|
||||
STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_prefetch_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424150 /* PABT */
|
||||
STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_data_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424144 /* DABT */
|
||||
STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
.globl irq_enable_cpu_irq_exceptions
|
||||
.type irq_enable_cpu_irq_exceptions, %function
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
#ifndef _FATFS_CFG_H_
|
||||
#define _FATFS_CFG_H_
|
||||
|
||||
// define FFCFG_INC in a project to use a specific FatFS configuration.
|
||||
// Example: FFCFG_INC := '"../$(PROJECT_DIR)/libs/fatfs/ffconf.h"'
|
||||
#ifdef FFCFG_INC
|
||||
#include FFCFG_INC
|
||||
#else
|
||||
#include "fatfs_conf.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
305
bdk/fatfs_conf.h
Normal file
305
bdk/fatfs_conf.h
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 1
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
#if FF_USE_MKFS
|
||||
#define FF_MKFS_LABEL "SWITCH SD "
|
||||
#endif
|
||||
/* This sets FAT/FAT32 label. Exactly 11 characters, all caps. */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
#define FF_FASTFS 0
|
||||
#if FF_FASTFS
|
||||
#undef FF_USE_FASTSEEK
|
||||
#define FF_USE_FASTSEEK 1
|
||||
#endif
|
||||
/* This option switches fast access to chained clusters. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_SIMPLE_GPT 1
|
||||
/* This option switches support for the first GPT partition. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 3
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 0
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "sd"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
/ Order is important. Any change to order, must also be reflected to diskio drive enum.
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 1
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2022
|
||||
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
739
bdk/gfx/di.c
739
bdk/gfx/di.c
|
@ -1,739 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "di.h"
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include "di.inl"
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
static u32 _display_id = 0;
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit);
|
||||
|
||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
{
|
||||
u32 end = get_tmr_us() + timeout;
|
||||
while (get_tmr_us() < end && DSI(off) & mask)
|
||||
;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
|
||||
{
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (param << 8) | cmd;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
if (wait)
|
||||
usleep(wait);
|
||||
}
|
||||
|
||||
static void _display_dsi_read_rx_fifo(u32 *data)
|
||||
{
|
||||
u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
|
||||
for (u32 i = 0; i < fifo_count; i++)
|
||||
{
|
||||
// Read or Drain RX FIFO.
|
||||
if (data)
|
||||
data[i] = DSI(_DSIREG(DSI_RD_DATA));
|
||||
else
|
||||
(void)DSI(_DSIREG(DSI_RD_DATA));
|
||||
}
|
||||
}
|
||||
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
int res = 0;
|
||||
u32 host_control = 0;
|
||||
u32 cmd_timeout = video_enabled ? 0 : 250000;
|
||||
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||
|
||||
// Drain RX FIFO.
|
||||
_display_dsi_read_rx_fifo(NULL);
|
||||
|
||||
// Save host control and enable host cmd packets during video.
|
||||
if (video_enabled)
|
||||
{
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
|
||||
|
||||
// Use the 4th line to transmit the host cmd packet.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
||||
|
||||
// Wait for vblank before starting the transfer.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
|
||||
;
|
||||
}
|
||||
|
||||
// Set reply size.
|
||||
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Request register read.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Transfer bus control to device for transmitting the reply.
|
||||
u32 high_speed = video_enabled ? DSI_HOST_CONTROL_HS : 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC | high_speed;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
// Wait a bit for the reply.
|
||||
usleep(5000);
|
||||
|
||||
// Read RX FIFO.
|
||||
_display_dsi_read_rx_fifo(fifo);
|
||||
|
||||
// Parse packet and copy over the data.
|
||||
if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
|
||||
{
|
||||
// Act based on reply type.
|
||||
switch (fifo[1] & 0xFF)
|
||||
{
|
||||
case GEN_LONG_RD_RES:
|
||||
case DCS_LONG_RD_RES:
|
||||
memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
|
||||
break;
|
||||
|
||||
case GEN_1_BYTE_SHORT_RD_RES:
|
||||
case DCS_1_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 1);
|
||||
break;
|
||||
|
||||
case GEN_2_BYTE_SHORT_RD_RES:
|
||||
case DCS_2_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 2);
|
||||
break;
|
||||
case ACK_ERROR_RES:
|
||||
default:
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
{
|
||||
// Wait for vblank before reseting sync points.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
|
||||
;
|
||||
|
||||
// Reset all states of syncpt block.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Clear syncpt block reset.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Restore video mode and host control.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
|
||||
// Disable and clear vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
u32 host_control;
|
||||
u32 fifo32[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||
u8 *fifo8 = (u8 *)fifo32;
|
||||
|
||||
// Enable host cmd packets during video and save host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable host transfer trigger.
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_TX_TRIG_HOST;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
|
||||
fifo8[4] = cmd;
|
||||
memcpy(&fifo8[5], data, len);
|
||||
len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
|
||||
for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for the write to happen.
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST);
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
}
|
||||
|
||||
void display_init()
|
||||
{
|
||||
// Check if display is already initialized.
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & BIT(CLK_L_DISP1))
|
||||
_display_panel_and_hw_end(true);
|
||||
|
||||
// Get Chip ID.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// T210B01: Power on SD2 regulator for supplying LDO0.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
// Set SD2 regulator voltage.
|
||||
max77620_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
||||
|
||||
// Set slew rate and enable SD2 regulator.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
||||
max77620_regulator_enable(REGULATOR_SD2, 1);
|
||||
|
||||
}
|
||||
|
||||
// Enable power to display panel controller.
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.
|
||||
if (tegra_t210)
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7,
|
||||
MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); // T210: LD0 -> GPIO7 -> Display panel.
|
||||
|
||||
// Enable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
|
||||
|
||||
// Bring every IO rail out of deep power down.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
|
||||
// Configure LCD pins.
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Configure Backlight pins.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Set LCD +-5V pins mode and direction
|
||||
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable LCD power.
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable.
|
||||
usleep(10000);
|
||||
|
||||
// Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST).
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable Backlight power.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
|
||||
|
||||
// Power up supply regulator for display interface.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
|
||||
|
||||
if (!tegra_t210)
|
||||
{
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
|
||||
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
||||
}
|
||||
|
||||
// Set DISP1 clock source and parent clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT.
|
||||
u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 96 MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
|
||||
// Setup Display Interface initial window configuration.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
|
||||
|
||||
// Setup display communication interfaces.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8);
|
||||
if (tegra_t210)
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
|
||||
else
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part2, 14);
|
||||
if (!tegra_t210)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part3_t210b01, 7);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part4, 10);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part5, 12);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part6, 14);
|
||||
usleep(10000);
|
||||
|
||||
// Enable LCD Reset.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
|
||||
usleep(60000);
|
||||
|
||||
// Setup DSI device takeover timeout.
|
||||
DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
|
||||
|
||||
#if 0
|
||||
// Get Display ID.
|
||||
_display_id = 0xCCCCCC;
|
||||
display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED);
|
||||
#else
|
||||
// Set reply size.
|
||||
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0);
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Request register read.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0);
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Transfer bus control to device for transmitting the reply.
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
// Wait a bit for the reply.
|
||||
usleep(5000);
|
||||
|
||||
// MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 x u32.
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
_display_id = DSI(_DSIREG(DSI_RD_DATA)) & 0xFFFFFF; // Skip ack and msg type info and get the payload (display id).
|
||||
#endif
|
||||
// Save raw Display ID to Nyx storage.
|
||||
nyx_str->info.disp_id = _display_id;
|
||||
|
||||
// Decode Display ID.
|
||||
_display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
|
||||
// Initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
case PANEL_AUO_A062TAN01:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
|
||||
if (_display_id == PANEL_INL_P062CCA_AZ1)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else // PANEL_AUO_A062TAN01.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
default: // Allow spare part displays to work.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
|
||||
break;
|
||||
}
|
||||
|
||||
// Unblank display.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||
|
||||
// Configure PLLD for DISP1.
|
||||
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 230.4 MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP
|
||||
else
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
|
||||
|
||||
// Finalize DSI configuration.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19);
|
||||
// Set pixel clock dividers: 230.4 / 3 / 1 = 76.8 MHz. 60 Hz.
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
|
||||
usleep(10000);
|
||||
|
||||
// Calibrate display communication pads.
|
||||
u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4);
|
||||
for (u32 i = 0; i < loops; i++)
|
||||
{
|
||||
// Set MIPI bias pad config.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
|
||||
|
||||
// Set pad trimmers and set MIPI DSI cal offsets.
|
||||
if (tegra_t210)
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210, 4);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210b01, 7);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210b01, 4);
|
||||
}
|
||||
|
||||
// Set the rest of MIPI cal offsets and apply calibration.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
|
||||
}
|
||||
usleep(10000);
|
||||
|
||||
// Enable video display controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113);
|
||||
}
|
||||
|
||||
void display_backlight_pwm_init()
|
||||
{
|
||||
clock_enable_pwm();
|
||||
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
||||
}
|
||||
|
||||
void display_backlight(bool enable)
|
||||
{
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
|
||||
}
|
||||
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay)
|
||||
{
|
||||
u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
|
||||
if (brightness == old_value)
|
||||
return;
|
||||
|
||||
if (brightness > 255)
|
||||
brightness = 255;
|
||||
|
||||
if (old_value < brightness)
|
||||
{
|
||||
for (u32 i = old_value; i < brightness + 1; i++)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = old_value; i > brightness; i--)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
if (!brightness)
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
|
||||
}
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||
{
|
||||
if (no_panel_deinit)
|
||||
goto skip_panel_deinit;
|
||||
|
||||
display_backlight_brightness(0, 1000);
|
||||
|
||||
// Enable host cmd packets during video.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
|
||||
// Blank display.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
||||
|
||||
// Propagate changes to all register buffers and disable host cmd packets during video.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
|
||||
// De-initialize video controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_timing_deinit_config, 16);
|
||||
usleep(10000);
|
||||
|
||||
// De-initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
|
||||
break;
|
||||
|
||||
case PANEL_AUO_A062TAN01:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
if (_display_id == PANEL_INL_2J055IA_27A)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else if (_display_id == PANEL_AUO_A055TAN01)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
else // PANEL_V40_55_UNK.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40).
|
||||
if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01)
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
|
||||
}
|
||||
else // PANEL_V40_55_UNK.
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
|
||||
}
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Blank - powerdown.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000);
|
||||
|
||||
skip_panel_deinit:
|
||||
// Disable LCD power pins.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable.
|
||||
usleep(10000);
|
||||
|
||||
// Disable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
// Power down pads.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
||||
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
|
||||
|
||||
// Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
}
|
||||
|
||||
void display_end() { _display_panel_and_hw_end(false); };
|
||||
|
||||
u16 display_get_decoded_panel_id()
|
||||
{
|
||||
return _display_id;
|
||||
}
|
||||
|
||||
void display_set_decoded_panel_id(u32 id)
|
||||
{
|
||||
// Decode Display ID.
|
||||
_display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
}
|
||||
|
||||
void display_color_screen(u32 color)
|
||||
{
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
|
||||
|
||||
// Configure display to show single color.
|
||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
||||
usleep(35000);
|
||||
|
||||
display_backlight(true);
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch()
|
||||
{
|
||||
// Sanitize framebuffer area.
|
||||
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
|
||||
|
||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)IPL_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch_inv()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
|
||||
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_block()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34);
|
||||
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_log()
|
||||
{
|
||||
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
|
||||
|
||||
return (u32 *)LOG_FB_ADDRESS;
|
||||
}
|
||||
|
||||
void display_activate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
|
||||
for (u32 i = 0xFF80; i < 0x10000; i++)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deactivate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
|
||||
for (u32 i = 0xFFFF; i > 0xFF7F; i--)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(500);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_init_cursor(void *crs_fb, u32 size)
|
||||
{
|
||||
// Setup cursor.
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) =
|
||||
CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
|
||||
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
|
||||
|
||||
// Arm and activate changes.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_set_pos_cursor(u32 x, u32 y)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
|
||||
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deinit_cursor()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
|
@ -29,33 +29,34 @@
|
|||
|
||||
#ifndef ELF_H
|
||||
#define ELF_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t Elf_Byte;
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef uint32_t Elf32_Addr; /* Unsigned program address */
|
||||
typedef uint32_t Elf32_Off; /* Unsigned file offset */
|
||||
typedef int32_t Elf32_Sword; /* Signed large integer */
|
||||
typedef uint32_t Elf32_Word; /* Unsigned large integer */
|
||||
typedef uint16_t Elf32_Half; /* Unsigned medium integer */
|
||||
typedef u8 Elf_Byte;
|
||||
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Shalf;
|
||||
typedef u32 Elf32_Addr; /* Unsigned program address */
|
||||
typedef u32 Elf32_Off; /* Unsigned file offset */
|
||||
typedef s32 Elf32_Sword; /* Signed large integer */
|
||||
typedef u32 Elf32_Word; /* Unsigned large integer */
|
||||
typedef u16 Elf32_Half; /* Unsigned medium integer */
|
||||
|
||||
typedef u64 Elf64_Addr;
|
||||
typedef u64 Elf64_Off;
|
||||
typedef s32 Elf64_Shalf;
|
||||
|
||||
#ifdef __alpha__
|
||||
typedef int64_t Elf64_Sword;
|
||||
typedef uint64_t Elf64_Word;
|
||||
typedef s64 Elf64_Sword;
|
||||
typedef u64 Elf64_Word;
|
||||
#else
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef s32 Elf64_Sword;
|
||||
typedef u32 Elf64_Word;
|
||||
#endif
|
||||
|
||||
typedef int64_t Elf64_Sxword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef s64 Elf64_Sxword;
|
||||
typedef u64 Elf64_Xword;
|
||||
|
||||
typedef uint32_t Elf64_Half;
|
||||
typedef uint16_t Elf64_Quarter;
|
||||
typedef u32 Elf64_Half;
|
||||
typedef u16 Elf64_Quarter;
|
||||
|
||||
/*
|
||||
* e_ident[] identification indexes
|
||||
|
@ -376,7 +377,7 @@ typedef struct
|
|||
|
||||
#define ELF64_R_SYM(info) ((info) >> 32)
|
||||
#define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t))
|
||||
#define ELF64_R_INFO(s, t) (((s) << 32) + (u32)(t))
|
||||
|
||||
#if defined(__mips64__) && defined(__MIPSEL__)
|
||||
/*
|
||||
|
@ -389,7 +390,7 @@ typedef struct
|
|||
#undef ELF64_R_INFO
|
||||
#define ELF64_R_TYPE(info) (swap32((info) >> 32))
|
||||
#define ELF64_R_SYM(info) ((info)&0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))
|
||||
#define ELF64_R_INFO(s, t) (((u64)swap32(t) << 32) + (u32)(s))
|
||||
#endif /* __mips64__ && __MIPSEL__ */
|
||||
|
||||
/* Program Header */
|
||||
|
@ -444,7 +445,7 @@ typedef struct
|
|||
/* Dynamic structure */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
Elf32_Word d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
|
|
|
@ -25,7 +25,7 @@ el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)
|
|||
}
|
||||
|
||||
#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
for (; *i < ctx->ehdr.e_phnum; (*i)++)
|
||||
|
@ -44,7 +44,7 @@ el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)
|
|||
}
|
||||
|
||||
#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize))
|
||||
el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i)
|
||||
el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, u32 type, unsigned *i)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
|
@ -213,7 +213,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloc)
|
|||
return rv;
|
||||
}
|
||||
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 tag)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
size_t ndyn = ctx->dynsize / sizeof(Elf_Dyn);
|
||||
|
@ -231,7 +231,7 @@ el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)
|
|||
return EL_OK;
|
||||
}
|
||||
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type)
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type)
|
||||
{
|
||||
el_status rv = EL_OK;
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include "elfarch.h"
|
||||
#include "elf.h"
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <gfx_utils.h>
|
||||
#define EL_DEBUG(format, ...) \
|
||||
|
@ -100,7 +98,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloccb);
|
|||
* If the end of the phdrs table was reached, *i is set to -1 and the contents
|
||||
* of *phdr are undefined
|
||||
*/
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i);
|
||||
el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i);
|
||||
|
||||
/* Relocate the loaded executable */
|
||||
el_status el_relocate(el_ctx *ctx);
|
||||
|
@ -108,7 +106,7 @@ el_status el_relocate(el_ctx *ctx);
|
|||
/* find a dynamic table entry
|
||||
* returns the entry on success, dyn->d_tag = DT_NULL on failure
|
||||
*/
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type);
|
||||
el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 type);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -122,6 +120,6 @@ typedef struct
|
|||
* pass DT_REL or DT_RELA for type
|
||||
* sets ri->entrysize = 0 if not found
|
||||
*/
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type);
|
||||
el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
|
||||
el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)
|
||||
{
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info);
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info);
|
||||
uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr);
|
||||
u32 type = ELF_R_TYPE(rel->r_info);
|
||||
u32 sym = ELF_R_SYM(rel->r_info);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -53,9 +53,9 @@ el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)
|
|||
|
||||
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
|
||||
{
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info);
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info);
|
||||
uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr);
|
||||
u32 type = ELF_R_TYPE(rel->r_info);
|
||||
u32 sym = ELF_R_SYM(rel->r_info);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
|
||||
{
|
||||
uint32_t sym = ELF_R_SYM(rel->r_info); // Symbol offset
|
||||
uint32_t type = ELF_R_TYPE(rel->r_info); // Relocation Type
|
||||
uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr
|
||||
u32 sym = ELF_R_SYM(rel->r_info); // Symbol offset
|
||||
u32 type = ELF_R_TYPE(rel->r_info); // Relocation Type
|
||||
uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr); // Target Addr
|
||||
|
||||
#if 0 // For later symbol usage
|
||||
Elf32_Sym *elfSym;
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#include "elfload/elfload.h"
|
||||
#include <module.h>
|
||||
#include <mem/heap.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <storage/sd.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
@ -43,6 +44,10 @@ static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
|||
bdkParameters->memset = (memset_t)&memset;
|
||||
bdkParameters->sharedHeap = &_heap;
|
||||
|
||||
// Extra functions.
|
||||
bdkParameters->extension_magic = IANOS_EXT0;
|
||||
bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage;
|
||||
|
||||
entrypoint(moduleConfig, bdkParameters);
|
||||
}
|
||||
|
||||
|
@ -69,19 +74,16 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
el_ctx ctx;
|
||||
uintptr_t epaddr = 0;
|
||||
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
// Read library.
|
||||
fileBuf = sd_file_read(path, NULL);
|
||||
|
||||
if (!fileBuf)
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
// Set our relocated library's buffer.
|
||||
switch (type & 0xFFFF)
|
||||
|
@ -95,15 +97,15 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
}
|
||||
|
||||
if (!elfBuf)
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
// Load and relocate library.
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;
|
||||
if (el_load(&ctx, _ianos_alloc_cb))
|
||||
goto elfFreeOut;
|
||||
goto out_free;
|
||||
|
||||
if (el_relocate(&ctx))
|
||||
goto elfFreeOut;
|
||||
goto out_free;
|
||||
|
||||
// Launch.
|
||||
epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;
|
||||
|
@ -111,11 +113,11 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
|
||||
_ianos_call_ep(ep, moduleConfig);
|
||||
|
||||
elfFreeOut:
|
||||
out_free:
|
||||
free(fileBuf);
|
||||
elfBuf = NULL;
|
||||
fileBuf = NULL;
|
||||
|
||||
elfLoadFinalOut:
|
||||
out:
|
||||
return epaddr;
|
||||
}
|
162
bdk/input/als.c
162
bdk/input/als.c
|
@ -17,102 +17,140 @@
|
|||
*/
|
||||
|
||||
#include "als.h"
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define HOS_GAIN BH1730_GAIN_64X
|
||||
#define HOS_ITIME 38
|
||||
#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
|
||||
#define BH1730_DEFAULT_ICYCLE 38
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime)
|
||||
#define BH1730_INTERNAL_CLOCK_NS 2800
|
||||
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
|
||||
#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
|
||||
|
||||
#define BH1730_DEFAULT_ITIME_MS 100
|
||||
|
||||
#define BH1730_LUX_MULTIPLIER 3600
|
||||
#define BH1730_LUX_MULTIPLIER_AULA 1410
|
||||
|
||||
#define BH1730_LUX_MAX 100000
|
||||
|
||||
typedef struct _opt_win_cal_t
|
||||
{
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - itime));
|
||||
u32 rc;
|
||||
u32 cv;
|
||||
u32 ci;
|
||||
} opt_win_cal_t;
|
||||
|
||||
als_val->gain = gain;
|
||||
als_val->itime = itime;
|
||||
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
||||
static const opt_win_cal_t opt_win_cal_default[] = {
|
||||
{ 500, 5002, 7502 },
|
||||
{ 754, 2250, 2000 },
|
||||
{ 1029, 1999, 1667 },
|
||||
{ 1373, 884, 583 },
|
||||
{ 1879, 309, 165 }
|
||||
};
|
||||
|
||||
// Nintendo Switch Aula Optical Window calibration.
|
||||
static const opt_win_cal_t opt_win_cal_aula[] = {
|
||||
{ 231, 9697, 30300 },
|
||||
{ 993, 3333, 2778 },
|
||||
{ 1478, 1621, 1053 },
|
||||
{ 7500, 81, 10 }
|
||||
};
|
||||
|
||||
static const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
||||
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||
{
|
||||
if (gain > BH1730_GAIN_128X)
|
||||
gain = BH1730_GAIN_128X;
|
||||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
als_ctxt->gain = gain;
|
||||
als_ctxt->cycle = cycle;
|
||||
}
|
||||
|
||||
void get_als_lux(als_table_t *als_val)
|
||||
void get_als_lux(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
u32 data[2];
|
||||
float pre_gain_lux;
|
||||
float visible_light;
|
||||
float ir_light;
|
||||
float light_ratio;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u64 lux = 0;
|
||||
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
|
||||
|
||||
u8 adc_ready = 0;
|
||||
u8 retries = 100;
|
||||
|
||||
const float als_gain_idx_tbl[4] = { 1.0, 2.0, 64.0, 128.0 };
|
||||
const float als_norm_res = 100.0;
|
||||
const float als_multiplier = 3.6;
|
||||
const float als_tint = 2.7;
|
||||
|
||||
// Wait for ADC to prepare new data.
|
||||
while (!(adc_ready & BH1730_CTL_ADC_VALID) && retries)
|
||||
{
|
||||
retries--;
|
||||
adc_ready = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG));
|
||||
}
|
||||
|
||||
// Get visible and ir light raw data.
|
||||
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
|
||||
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
|
||||
als_val->over_limit = data[0] > 65534 || data[1] > 65534;
|
||||
als_val->vi_light = data[0];
|
||||
als_val->ir_light = data[1];
|
||||
vi_light = data[0];
|
||||
ir_light = data[1];
|
||||
|
||||
if (!data[0] || !retries)
|
||||
als_ctxt->vi_light = vi_light;
|
||||
als_ctxt->ir_light = ir_light;
|
||||
als_ctxt->over_limit = vi_light > 65534 || ir_light > 65534;
|
||||
|
||||
if (!vi_light)
|
||||
{
|
||||
als_val->lux = 0.0;
|
||||
als_ctxt->lux = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
visible_light = (float)data[0];
|
||||
ir_light = (float)data[1];
|
||||
light_ratio = (float)data[1] / (float)data[0];
|
||||
// Set calibration parameters.
|
||||
u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
|
||||
u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
|
||||
const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
|
||||
|
||||
// The following are specific to the light filter Switch uses.
|
||||
if (light_ratio < 0.5)
|
||||
pre_gain_lux = visible_light * 5.002 - ir_light * 7.502;
|
||||
else if (light_ratio < 0.754)
|
||||
pre_gain_lux = visible_light * 2.250 - ir_light * 2.000;
|
||||
else if (light_ratio < 1.029)
|
||||
pre_gain_lux = visible_light * 1.999 - ir_light * 1.667;
|
||||
else if (light_ratio < 1.373)
|
||||
pre_gain_lux = visible_light * 0.884 - ir_light * 0.583;
|
||||
else if (light_ratio < 1.879)
|
||||
pre_gain_lux = visible_light * 0.309 - ir_light * 0.165;
|
||||
else pre_gain_lux = 0.0;
|
||||
// Apply optical window calibration coefficients.
|
||||
for (u32 i = 0; i < opt_win_cal_count; i++)
|
||||
{
|
||||
if (1000 * ir_light / vi_light < opt_win_cal[i].rc)
|
||||
{
|
||||
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
als_val->lux = (pre_gain_lux / als_gain_idx_tbl[als_val->gain]) * (als_norm_res / ((float)als_val->itime * als_tint)) * als_multiplier;
|
||||
lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
|
||||
lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
|
||||
lux /= 1000;
|
||||
|
||||
if (lux > BH1730_LUX_MAX)
|
||||
lux = BH1730_LUX_MAX;
|
||||
|
||||
als_ctxt->lux = lux;
|
||||
}
|
||||
|
||||
u8 als_init(als_table_t *als_val)
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
// Enable power to ALS IC.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Init I2C2.
|
||||
pinmux_config_i2c(I2C_2);
|
||||
clock_enable_i2c(I2C_2);
|
||||
i2c_init(I2C_2);
|
||||
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
(MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
|
||||
|
||||
// Initialize ALS.
|
||||
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), HOS_GAIN);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - HOS_ITIME));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
als_val->gain = HOS_GAIN;
|
||||
als_val->itime = HOS_ITIME;
|
||||
set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -48,18 +48,18 @@
|
|||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
|
||||
|
||||
typedef struct _als_table_t
|
||||
typedef struct _als_ctxt_t
|
||||
{
|
||||
float lux;
|
||||
u32 lux;
|
||||
bool over_limit;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 itime;
|
||||
} als_table_t;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 cycle;
|
||||
} als_ctxt_t;
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
|
||||
void get_als_lux(als_table_t *als_val);
|
||||
u8 als_init(als_table_t *als_val);
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
|
||||
void get_als_lux(als_ctxt_t *als_ctxt);
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt);
|
||||
|
||||
#endif /* __ALS_H_ */
|
||||
|
|
1019
bdk/input/joycon.c
1019
bdk/input/joycon.c
File diff suppressed because it is too large
Load diff
|
@ -43,34 +43,34 @@ typedef struct _jc_gamepad_rpt_t
|
|||
struct
|
||||
{
|
||||
// Joy-Con (R).
|
||||
u32 y:1;
|
||||
u32 x:1;
|
||||
u32 b:1;
|
||||
u32 a:1;
|
||||
u32 sr_r:1;
|
||||
u32 sl_r:1;
|
||||
u32 r:1;
|
||||
u32 zr:1;
|
||||
/*00*/ u32 y:1;
|
||||
/*01*/ u32 x:1;
|
||||
/*02*/ u32 b:1;
|
||||
/*03*/ u32 a:1;
|
||||
/*04*/ u32 sr_r:1;
|
||||
/*05*/ u32 sl_r:1;
|
||||
/*06*/ u32 r:1;
|
||||
/*07*/ u32 zr:1;
|
||||
|
||||
// Shared
|
||||
u32 minus:1;
|
||||
u32 plus:1;
|
||||
u32 r3:1;
|
||||
u32 l3:1;
|
||||
u32 home:1;
|
||||
u32 cap:1;
|
||||
u32 pad:1;
|
||||
u32 wired:1;
|
||||
/*08*/ u32 minus:1;
|
||||
/*09*/ u32 plus:1;
|
||||
/*10*/ u32 r3:1;
|
||||
/*11*/ u32 l3:1;
|
||||
/*12*/ u32 home:1;
|
||||
/*13*/ u32 cap:1;
|
||||
/*14*/ u32 pad:1;
|
||||
/*15*/ u32 wired:1;
|
||||
|
||||
// Joy-Con (L).
|
||||
u32 down:1;
|
||||
u32 up:1;
|
||||
u32 right:1;
|
||||
u32 left:1;
|
||||
u32 sr_l:1;
|
||||
u32 sl_l:1;
|
||||
u32 l:1;
|
||||
u32 zl:1;
|
||||
/*16*/ u32 down:1;
|
||||
/*17*/ u32 up:1;
|
||||
/*18*/ u32 right:1;
|
||||
/*19*/ u32 left:1;
|
||||
/*20*/ u32 sr_l:1;
|
||||
/*21*/ u32 sl_l:1;
|
||||
/*22*/ u32 l:1;
|
||||
/*23*/ u32 zl:1;
|
||||
};
|
||||
u32 buttons;
|
||||
};
|
||||
|
@ -83,16 +83,26 @@ typedef struct _jc_gamepad_rpt_t
|
|||
bool center_stick_r;
|
||||
bool conn_l;
|
||||
bool conn_r;
|
||||
u8 batt_info_l;
|
||||
u8 batt_info_r;
|
||||
bool sio_mode;
|
||||
u8 batt_info_l; // Also Sio Connected status.
|
||||
u8 batt_info_r; // Also Sio IRQ.
|
||||
jc_bt_conn_t bt_conn_l;
|
||||
jc_bt_conn_t bt_conn_r;
|
||||
} jc_gamepad_rpt_t;
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable);
|
||||
typedef struct _jc_calib_t
|
||||
{
|
||||
u16 x_max:12;
|
||||
u16 y_max:12;
|
||||
u16 x_center:12;
|
||||
u16 y_center:12;
|
||||
u16 x_min:12;
|
||||
u16 y_min:12;
|
||||
} __attribute__((packed)) jc_calib_t;
|
||||
|
||||
void jc_init_hw();
|
||||
void jc_deinit();
|
||||
jc_gamepad_rpt_t *joycon_poll();
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -23,17 +23,26 @@
|
|||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <power/max77620.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/util.h>
|
||||
#include "touch.h"
|
||||
|
||||
|
||||
#include <gfx_utils.h>
|
||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
|
||||
static touch_panel_info_t _panels[] =
|
||||
{
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0.
|
||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
|
||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
|
||||
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
|
||||
{ 4, 0, 0, 1, "Samsung TSP" },// 5?
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
|
||||
};
|
||||
|
||||
static int touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
|
||||
|
@ -53,7 +62,7 @@ static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout)
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
{
|
||||
u32 timer = get_tmr_ms() + timeout;
|
||||
while (true)
|
||||
|
@ -61,7 +70,11 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout)
|
|||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == event && tmp[2] == status)
|
||||
{
|
||||
if (buf)
|
||||
memcpy(buf, &tmp[3], 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
return 1;
|
||||
|
@ -74,19 +87,19 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout)
|
|||
|
||||
static void _touch_compensate_limits(touch_event *event, bool touching)
|
||||
{
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
event->x -= EDGE_OFFSET;
|
||||
u32 x_adj = (1280 * 1000) / (X_REAL_MAX - EDGE_OFFSET);
|
||||
event->x = ((u32)event->x * x_adj) / 1000;
|
||||
event->x = ((u32)event->x * x_adj) / 1000;
|
||||
|
||||
if (touching)
|
||||
{
|
||||
event->y = MAX(event->y, EDGE_OFFSET);
|
||||
event->y = MIN(event->y, Y_REAL_MAX);
|
||||
event->y = MAX(event->y, EDGE_OFFSET);
|
||||
event->y = MIN(event->y, Y_REAL_MAX);
|
||||
event->y -= EDGE_OFFSET;
|
||||
u32 y_adj = (720 * 1000) / (Y_REAL_MAX - EDGE_OFFSET);
|
||||
event->y = ((u32)event->y * y_adj) / 1000;
|
||||
event->y = ((u32)event->y * y_adj) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,6 +115,7 @@ static void _touch_process_contact_event(touch_event *event, bool touching)
|
|||
|
||||
event->z = event->raw[5] | (event->raw[6] << 8);
|
||||
event->z = event->z << 6;
|
||||
|
||||
u16 tmp = 0x40;
|
||||
if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F)
|
||||
tmp = event->raw[7] & 0x3F;
|
||||
|
@ -147,10 +161,10 @@ static void _touch_parse_event(touch_event *event)
|
|||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
|
||||
// gfx_con_setpos(&gfx_con, 0, 300);
|
||||
// gfx_con_setpos(0, 300);
|
||||
// DPRINTF("x = %d \ny = %d \nz = %d \n", event->x, event->y, event->z);
|
||||
// DPRINTF("0 = %02X\n1 = %02x\n2 = %02x\n3 = %02x\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02x\n6 = %02x\n7 = %02x\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
// DPRINTF("0 = %02X\n1 = %02X\n2 = %02X\n3 = %02X\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02X\n6 = %02X\n7 = %02X\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
}
|
||||
|
||||
void touch_poll(touch_event *event)
|
||||
|
@ -183,16 +197,45 @@ touch_info touch_get_info()
|
|||
info.config_id = buf[4];
|
||||
info.config_ver = buf[5];
|
||||
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02x, Cfg Ver: %d\n",
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02X, Cfg Ver: %d\n",
|
||||
// info.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
touch_panel_info_t *touch_get_panel_vendor()
|
||||
{
|
||||
u8 buf[5] = {0};
|
||||
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
||||
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
|
||||
|
||||
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
||||
return NULL;
|
||||
|
||||
if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
|
||||
return NULL;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_panels); i++)
|
||||
{
|
||||
touch_panel_info_t *panel = &_panels[i];
|
||||
if (buf[0] == panel->gpio0 && buf[1] == panel->gpio1 && buf[2] == panel->gpio2)
|
||||
return panel;
|
||||
}
|
||||
|
||||
// Touch panel not found, return current gpios.
|
||||
panel_info.gpio0 = buf[0];
|
||||
panel_info.gpio1 = buf[1];
|
||||
panel_info.gpio2 = buf[2];
|
||||
|
||||
return &panel_info;
|
||||
}
|
||||
|
||||
int touch_get_fw_info(touch_fw_info_t *fw)
|
||||
{
|
||||
u8 buf[8] = {0};
|
||||
|
||||
memset(fw, 0, sizeof(touch_fw_info_t));
|
||||
|
||||
// Get fw address info.
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
||||
int res = touch_read_reg(cmd, 3, buf, 3);
|
||||
|
@ -203,7 +246,7 @@ int touch_get_fw_info(touch_fw_info_t *fw)
|
|||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
if (!res)
|
||||
{
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->ftb_ver = (buf[6] << 8) | buf[5];
|
||||
}
|
||||
|
||||
|
@ -227,7 +270,7 @@ int touch_sys_reset()
|
|||
continue;
|
||||
}
|
||||
msleep(10);
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20))
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL))
|
||||
continue;
|
||||
else
|
||||
return 0;
|
||||
|
@ -284,7 +327,7 @@ int touch_get_fb_info(u8 *buf)
|
|||
int res = 0;
|
||||
|
||||
|
||||
for (u32 i = 0; i < 0x10000; i+=4)
|
||||
for (u32 i = 0; i < 0x10000; i += 4)
|
||||
{
|
||||
if (!res)
|
||||
{
|
||||
|
@ -301,9 +344,9 @@ int touch_get_fb_info(u8 *buf)
|
|||
|
||||
int touch_sense_enable()
|
||||
{
|
||||
// Enable auto tuning calibration and multi-touch sensing.
|
||||
u8 cmd = 1;
|
||||
if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1))
|
||||
// Switch sense mode and enable multi-touch sensing.
|
||||
u8 cmd = STMFTS_FINGER_MODE;
|
||||
if (touch_command(STMFTS_SWITCH_SENSE_MODE, &cmd, 1))
|
||||
return 0;
|
||||
|
||||
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
|
||||
|
@ -329,19 +372,19 @@ int touch_execute_autotune()
|
|||
// Apply Mutual Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Apply Self Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Save Compensation data to EEPROM.
|
||||
if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
return touch_sense_enable();
|
||||
|
@ -358,34 +401,32 @@ static int touch_init()
|
|||
|
||||
int touch_power_on()
|
||||
{
|
||||
// Enables LDO6 for touchscreen VDD/AVDD supply
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
(MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
|
||||
|
||||
// Configure touchscreen GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||
|
||||
// IRQ and more.
|
||||
// PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3;
|
||||
// gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
// gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW);
|
||||
|
||||
// Configure Touscreen and GCAsic shared GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2; // Unused.
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||
|
||||
// Configure touchscreen Touch Reset pin.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
usleep(20);
|
||||
|
||||
// Enable LDO6 for touchscreen AVDD and DVDD supply.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Initialize I2C3.
|
||||
pinmux_config_i2c(I2C_3);
|
||||
clock_enable_i2c(I2C_3);
|
||||
i2c_init(I2C_3);
|
||||
usleep(1000);
|
||||
|
||||
// Set Touch Reset pin.
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||
usleep(10000);
|
||||
|
||||
// Wait for the touchscreen module to get ready.
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20);
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
|
||||
// Check for forced boot time calibration.
|
||||
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
|
@ -414,9 +455,7 @@ void touch_power_off()
|
|||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
|
||||
// Disables LDO6 for touchscreen VDD, AVDD supply
|
||||
max77620_regulator_enable(REGULATOR_LDO6, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
MAX77620_LDO_CFG2_ADE_ENABLE | (2 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, false);
|
||||
|
||||
clock_disable_i2c(I2C_3);
|
||||
}
|
|
@ -47,19 +47,27 @@
|
|||
#define STMFTS_ITO_CHECK 0xA7
|
||||
#define STMFTS_RELEASEINFO 0xAA
|
||||
#define STMFTS_WRITE_REG 0xB6
|
||||
#define STMFTS_AUTO_CALIBRATION 0xC3
|
||||
#define STMFTS_SWITCH_SENSE_MODE 0xC3
|
||||
#define STMFTS_NOISE_WRITE 0xC7
|
||||
#define STMFTS_NOISE_READ 0xC8
|
||||
#define STMFTS_RW_FRAMEBUFFER_REG 0xD0
|
||||
#define STMFTS_SAVE_CX_TUNING 0xFC
|
||||
|
||||
#define STMFTS_UNK0 0xB8 //Request compensation
|
||||
#define STMFTS_UNK1 0xCF
|
||||
#define STMFTS_UNK2 0xF7
|
||||
#define STMFTS_UNK3 0xFA
|
||||
#define STMFTS_UNK4 0xF9
|
||||
#define STMFTS_DETECTION_CONFIG 0xB0
|
||||
#define STMFTS_REQU_COMP_DATA 0xB8
|
||||
#define STMFTS_VENDOR 0xCF
|
||||
#define STMFTS_FLASH_UNLOCK 0xF7
|
||||
#define STMFTS_FLASH_WRITE_64K 0xF8
|
||||
#define STMFTS_FLASH_STATUS 0xF9
|
||||
#define STMFTS_FLASH_OP 0xFA
|
||||
#define STMFTS_UNK5 0x62
|
||||
|
||||
/* cmd parameters */
|
||||
#define STMFTS_VENDOR_GPIO_STATE 0x01
|
||||
#define STMFTS_VENDOR_SENSE_MODE 0x02
|
||||
#define STMFTS_STYLUS_MODE 0x00
|
||||
#define STMFTS_FINGER_MODE 0x01
|
||||
#define STMFTS_HOVER_MODE 0x02
|
||||
|
||||
/* events */
|
||||
#define STMFTS_EV_NO_EVENT 0x00
|
||||
|
@ -74,6 +82,7 @@
|
|||
#define STMFTS_EV_ERROR 0x0f
|
||||
#define STMFTS_EV_NOISE_READ 0x17
|
||||
#define STMFTS_EV_NOISE_WRITE 0x18
|
||||
#define STMFTS_EV_VENDOR 0x20
|
||||
|
||||
#define STMFTS_EV_CONTROLLER_READY 0x10
|
||||
#define STMFTS_EV_STATUS 0x16
|
||||
|
@ -131,6 +140,15 @@ typedef struct _touch_event {
|
|||
bool touch;
|
||||
} touch_event;
|
||||
|
||||
typedef struct _touch_panel_info_t
|
||||
{
|
||||
u8 idx;
|
||||
u8 gpio0;
|
||||
u8 gpio1;
|
||||
u8 gpio2;
|
||||
char *vendor;
|
||||
} touch_panel_info_t;
|
||||
|
||||
typedef struct _touch_info {
|
||||
u16 chip_id;
|
||||
u16 fw_ver;
|
||||
|
@ -146,6 +164,7 @@ typedef struct _touch_fw_info_t {
|
|||
|
||||
void touch_poll(touch_event *event);
|
||||
touch_event touch_poll_wait();
|
||||
touch_panel_info_t *touch_get_panel_vendor();
|
||||
int touch_get_fw_info(touch_fw_info_t *fw);
|
||||
touch_info touch_get_info();
|
||||
int touch_panel_ito_test(u8 *err);
|
||||
|
|
|
@ -20,33 +20,33 @@
|
|||
|
||||
#include "blz.h"
|
||||
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)
|
||||
const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer)
|
||||
{
|
||||
if (compDataLen < sizeof(blz_footer))
|
||||
if (comp_data_size < sizeof(blz_footer))
|
||||
return NULL;
|
||||
|
||||
const blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];
|
||||
if (outFooter != NULL)
|
||||
memcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.
|
||||
const blz_footer *src_footer = (const blz_footer *)&comp_data[comp_data_size - sizeof(blz_footer)];
|
||||
if (out_footer)
|
||||
memcpy(out_footer, src_footer, sizeof(blz_footer)); // Must be a memcpy because no unaligned accesses on ARMv4.
|
||||
|
||||
return srcFooter;
|
||||
return src_footer;
|
||||
}
|
||||
|
||||
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer)
|
||||
int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer)
|
||||
{
|
||||
u32 addl_size = footer->addl_size;
|
||||
u32 header_size = footer->header_size;
|
||||
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
|
||||
|
||||
unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
|
||||
u8 *cmp_start = &data[comp_size] - cmp_and_hdr_size;
|
||||
u32 cmp_ofs = cmp_and_hdr_size - header_size;
|
||||
u32 out_ofs = cmp_and_hdr_size + addl_size;
|
||||
|
||||
while (out_ofs)
|
||||
{
|
||||
unsigned char control = cmp_start[--cmp_ofs];
|
||||
for (unsigned int i=0; i<8; i++)
|
||||
u8 control = cmp_start[--cmp_ofs];
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (control & 0x80)
|
||||
{
|
||||
|
@ -54,45 +54,48 @@ int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const
|
|||
return 0; // Out of bounds.
|
||||
|
||||
cmp_ofs -= 2;
|
||||
u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
||||
u16 seg_val = ((u32)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
|
||||
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
|
||||
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
|
||||
if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
|
||||
|
||||
// Kernel restricts segment copy to stay in bounds.
|
||||
if (out_ofs < seg_size)
|
||||
seg_size = out_ofs;
|
||||
|
||||
out_ofs -= seg_size;
|
||||
|
||||
for (unsigned int j = 0; j < seg_size; j++)
|
||||
for (u32 j = 0; j < seg_size; j++)
|
||||
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
|
||||
}
|
||||
else
|
||||
else // Copy directly.
|
||||
{
|
||||
// Copy directly.
|
||||
if (cmp_ofs < 1)
|
||||
return 0; //out of bounds
|
||||
return 0; // Out of bounds.
|
||||
|
||||
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
|
||||
}
|
||||
|
||||
control <<= 1;
|
||||
if (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.
|
||||
|
||||
if (!out_ofs) // Blz works backwards, so if it reaches byte 0, it's done.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)
|
||||
int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size)
|
||||
{
|
||||
blz_footer footer;
|
||||
const blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
|
||||
if (compFooterPtr == NULL)
|
||||
const blz_footer *comp_footer = blz_get_footer(comp_data, comp_data_size, &footer);
|
||||
if (!comp_footer)
|
||||
return 0;
|
||||
|
||||
// Decompression must be done in-place, so need to copy the relevant compressed data first.
|
||||
unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
|
||||
memcpy(dstData, compData, numCompBytes);
|
||||
memset(&dstData[numCompBytes], 0, dstSize - numCompBytes);
|
||||
// Decompression happens in-place, so need to copy the relevant compressed data first.
|
||||
u32 comp_bytes = (const u8 *)comp_footer - comp_data;
|
||||
memcpy(dst_data, comp_data, comp_bytes);
|
||||
memset(&dst_data[comp_bytes], 0, dst_size - comp_bytes);
|
||||
|
||||
return blz_uncompress_inplace(dstData, compDataLen, &footer);
|
||||
return blz_uncompress_inplace(dst_data, comp_data_size, &footer);
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ typedef struct _blz_footer
|
|||
u32 addl_size;
|
||||
} blz_footer;
|
||||
|
||||
// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.
|
||||
const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);
|
||||
// Returns pointer to footer in comp_data if present, additionally copies it to out_footer if not NULL.
|
||||
const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);
|
||||
int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer);
|
||||
// Returns 0 on failure.
|
||||
int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);
|
||||
int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -92,22 +92,12 @@
|
|||
# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
|
||||
# define expect(expr,value) (__builtin_expect ((expr),(value)) )
|
||||
#else
|
||||
# define expect(expr,value) (expr)
|
||||
#endif
|
||||
|
||||
#define likely(expr) expect((expr) != 0, 1)
|
||||
#define unlikely(expr) expect((expr) != 0, 0)
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Memory routines
|
||||
**************************************/
|
||||
#include <mem/heap.h> /* malloc, calloc, free */
|
||||
#define ALLOC(s) malloc(s)
|
||||
#define ALLOC_AND_ZERO(s) calloc(1,s)
|
||||
#define ALLOC_AND_ZERO(s) zalloc(s)
|
||||
#define FREEMEM free
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#define MEM_INIT memset
|
||||
|
@ -839,10 +829,12 @@ int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst
|
|||
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
int result;
|
||||
LZ4_stream_t ctx;
|
||||
LZ4_stream_t* const ctxPtr = &ctx;
|
||||
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
|
||||
LZ4_stream_t* const ctxPtr = ctx;
|
||||
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
|
||||
|
||||
FREEMEM(ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -857,13 +849,18 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO
|
|||
/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
|
||||
int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
LZ4_stream_t ctx;
|
||||
LZ4_resetStream(&ctx);
|
||||
int result;
|
||||
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
|
||||
LZ4_resetStream(ctx);
|
||||
|
||||
if (inputSize < LZ4_64Klimit)
|
||||
return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
||||
result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
||||
else
|
||||
return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
|
||||
FREEMEM(ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1045,11 +1042,13 @@ static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src,
|
|||
|
||||
int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
|
||||
{
|
||||
LZ4_stream_t ctxBody;
|
||||
LZ4_stream_t* ctx = &ctxBody;
|
||||
LZ4_stream_t* ctxBody = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));;
|
||||
LZ4_stream_t* ctx = ctxBody;
|
||||
|
||||
int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
|
||||
|
||||
FREEMEM(ctxBody);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ typedef enum {
|
|||
DRIVE_SD = 0,
|
||||
DRIVE_RAM = 1,
|
||||
DRIVE_EMMC = 2,
|
||||
DRIVE_BIS = 3
|
||||
DRIVE_BIS = 3,
|
||||
DRIVE_EMU = 4
|
||||
} DDRIVE;
|
||||
|
||||
|
||||
|
@ -59,6 +60,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
|||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
|
@ -3273,7 +3274,6 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
|||
stat = disk_status(fs->pdrv);
|
||||
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
|
||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
|
||||
EFSPRINTF("WPEN1");
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
return FR_OK; /* The filesystem object is valid */
|
||||
|
@ -3284,14 +3284,13 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
|||
/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */
|
||||
|
||||
fs->fs_type = 0; /* Clear the filesystem object */
|
||||
fs->part_type = 0; /* Clear the Partition object */
|
||||
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
|
||||
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
|
||||
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
|
||||
EFSPRINTF("MDNR");
|
||||
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
|
||||
}
|
||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */
|
||||
EFSPRINTF("WPEN2");
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
|
||||
|
@ -3318,6 +3317,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
|||
EFSPRINTF("BRNL");
|
||||
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
|
||||
}
|
||||
#if FF_SIMPLE_GPT
|
||||
if (fmt >= 2) {
|
||||
/* If GPT Check the first partition */
|
||||
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
|
||||
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
|
||||
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
|
||||
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
|
||||
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
|
||||
fs->part_type = 1;
|
||||
bsect = gpt_entry->lba_start;
|
||||
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fmt >= 2) {
|
||||
EFSPRINTF("NOFAT");
|
||||
return FR_NO_FILESYSTEM; /* No FAT volume is found */
|
||||
|
@ -4696,9 +4709,9 @@ DWORD *f_expand_cltbl (
|
|||
}
|
||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||
ff_memfree(fp->cltbl);
|
||||
fp->cltbl = NULL;
|
||||
fp->cltbl = (void *)0;
|
||||
EFSPRINTF("CLTBLSZ");
|
||||
return NULL;
|
||||
return (void *)0;
|
||||
}
|
||||
f_lseek(fp, 0);
|
||||
|
||||
|
@ -5866,7 +5879,7 @@ FRESULT f_mkfs (
|
|||
stat = disk_initialize(pdrv);
|
||||
if (stat & STA_NOINIT) return FR_NOT_READY;
|
||||
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
|
||||
if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */
|
||||
if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 131072 || (sz_blk & (sz_blk - 1))) sz_blk = 2048; /* Erase block to align data area. 1MB minimum */
|
||||
#if FF_MAX_SS != FF_MIN_SS /* Get sector size of the medium if variable sector size cfg. */
|
||||
if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;
|
||||
if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;
|
||||
|
@ -5902,7 +5915,7 @@ FRESULT f_mkfs (
|
|||
} else {
|
||||
/* Create a single-partition in this function */
|
||||
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
|
||||
b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */
|
||||
b_vol = (opt & FM_SFD) ? 0 : sz_blk; /* Volume start sector */
|
||||
if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||
sz_vol -= b_vol; /* Volume size */
|
||||
}
|
||||
|
@ -6169,7 +6182,9 @@ FRESULT f_mkfs (
|
|||
#endif
|
||||
/* Create FAT VBR */
|
||||
mem_set(buf, 0, ss);
|
||||
mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */
|
||||
/* Boot jump code (x86), OEM name */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||
st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */
|
||||
|
@ -6182,23 +6197,27 @@ FRESULT f_mkfs (
|
|||
}
|
||||
buf[BPB_Media] = 0xF8; /* Media descriptor byte */
|
||||
st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */
|
||||
st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */
|
||||
st_word(buf + BPB_NumHeads, (opt & FM_PRF2) ? 16 : 255); /* Number of heads (for int13) */
|
||||
st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */
|
||||
if (fmt == FS_FAT32) {
|
||||
st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BS_VolID32, (opt & FM_PRF2) ? 0 : GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */
|
||||
st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */
|
||||
st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */
|
||||
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
|
||||
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig32] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab32, FF_MKFS_LABEL "FAT32 ", 19);
|
||||
else mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19);
|
||||
} else {
|
||||
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
|
||||
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
|
||||
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab, FF_MKFS_LABEL "FAT ", 19);
|
||||
else mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19);
|
||||
}
|
||||
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
|
||||
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
|
||||
|
@ -6209,13 +6228,35 @@ FRESULT f_mkfs (
|
|||
mem_set(buf, 0, ss);
|
||||
st_dword(buf + FSI_LeadSig, 0x41615252);
|
||||
st_dword(buf + FSI_StrucSig, 0x61417272);
|
||||
st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
|
||||
st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */
|
||||
if (opt & FM_PRF2) {
|
||||
st_dword(buf + FSI_Free_Count, 0xFFFFFFFF); /* Invalidate free count */
|
||||
st_dword(buf + FSI_Nxt_Free, 0xFFFFFFFF); /* Invalidate last allocated cluster */
|
||||
} else {
|
||||
st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
|
||||
st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */
|
||||
}
|
||||
st_word(buf + BS_55AA, 0xAA55);
|
||||
disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */
|
||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||
}
|
||||
|
||||
/* Create PRF2SAFE info */
|
||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||
mem_set(buf, 0, ss);
|
||||
st_dword(buf + 0, 0x32465250); /* Magic PRF2 */
|
||||
st_dword(buf + 4, 0x45464153); /* Magic SAFE */
|
||||
buf[16] = 0x64; /* Record type */
|
||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
||||
if (sz_vol < 0x1000000) {
|
||||
st_dword(buf + 36, 21 + 1); /* 22 Entries. */
|
||||
st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */
|
||||
} else {
|
||||
st_dword(buf + 36, 21 + 2); /* 23 Entries. */
|
||||
st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */
|
||||
}
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
}
|
||||
|
||||
/* Initialize FAT area */
|
||||
mem_set(buf, 0, (UINT)szb_buf);
|
||||
sect = b_fat; /* FAT start sector */
|
||||
|
@ -6705,6 +6746,8 @@ int f_puts (
|
|||
putbuff pb;
|
||||
|
||||
|
||||
if (str == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
while (*str) putc_bfd(&pb, *str++); /* Put the string */
|
||||
return putc_flush(&pb);
|
||||
|
@ -6731,6 +6774,8 @@ int f_printf (
|
|||
TCHAR c, d, str[32], *p;
|
||||
|
||||
|
||||
if (fmt == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
|
||||
va_start(arp, fmt);
|
||||
|
|
|
@ -95,8 +95,8 @@ typedef DWORD FSIZE_t;
|
|||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE part_type; /* Partition type (0:MBR, 1:GPT) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
|
@ -138,6 +138,7 @@ typedef struct {
|
|||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg). DMA aligned. */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
@ -168,9 +169,6 @@ typedef struct {
|
|||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
|
@ -184,6 +182,9 @@ typedef struct {
|
|||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window. DMA aligned. */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
@ -365,6 +366,7 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
|||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
#define FM_PRF2 0x10
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C) ChaN, 2018 */
|
||||
/* (C) CTCaer, 2018 */
|
||||
/* (C) ChaN, 2018 */
|
||||
/* (C) CTCaer, 2018-2024 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include <bdk.h>
|
||||
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include "../../config.h"
|
||||
#include <mem/heap.h>
|
||||
#include <rtc/max77620-rtc.h>
|
||||
|
||||
extern nyx_config n_cfg;
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
|
@ -22,7 +18,8 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if no
|
|||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
// Ensure size is aligned to SDMMC block size.
|
||||
return malloc(ALIGN(msize, SDMMC_DAT_BLOCKSIZE)); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,12 +48,7 @@ DWORD get_fattime (
|
|||
{
|
||||
rtc_time_t time;
|
||||
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff);
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
max77620_rtc_get_time_adjusted(&time);
|
||||
|
||||
return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) |
|
||||
((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1));
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include <utils/types.h>
|
||||
#include <soc/timer.h>
|
||||
#include <memory_map.h>
|
||||
/*===================
|
||||
Dynamic memory
|
||||
|
@ -147,10 +147,10 @@
|
|||
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
|
||||
|
||||
/*HAL settings*/
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE <utils/util.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE <soc/timer.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((u32)get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
|
@ -296,6 +296,9 @@
|
|||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define USE_LV_MBOX 1
|
||||
#if USE_LV_MBOX != 0
|
||||
# define LV_MBOX_CLOSE_ANIM_TIME 200 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define USE_LV_TA 1
|
||||
|
|
|
@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
|
|||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
|||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
|
||||
/*Send a signal about the press*/
|
||||
|
|
|
@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
|||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
|
||||
#else
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
|
||||
((uint32_t) c & 0xFF))
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
|
||||
((uint32_t) (c) & 0xFF))
|
||||
#endif
|
||||
|
||||
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
|
||||
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
|
||||
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
|
||||
((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
|
||||
((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
|
|||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
{
|
||||
bool changed = ll_new_p->head != node;
|
||||
|
||||
lv_ll_rem(ll_ori_p, node);
|
||||
|
||||
/*Set node as head*/
|
||||
|
@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
|||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||
ll_new_p->tail = node;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
|
|||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
|
||||
/**
|
||||
* Return with head node of the linked list
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -32,13 +32,16 @@
|
|||
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
||||
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
||||
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
||||
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
|
||||
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
|
||||
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
|
||||
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
|
||||
#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
|
||||
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
||||
|
||||
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
|
||||
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
|
||||
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
|
||||
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
|
||||
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
@ -57,8 +60,9 @@ static lv_style_t def;
|
|||
static lv_style_t sb;
|
||||
|
||||
/*Saved input parameters*/
|
||||
static uint16_t _hue;
|
||||
static uint16_t _hue;
|
||||
static lv_font_t * _font;
|
||||
uint32_t theme_bg_color;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -80,18 +84,17 @@ static void basic_init(void)
|
|||
//def.image.opa = LV_OPA_COVER;
|
||||
|
||||
lv_style_copy(&bg, &def);
|
||||
bg.body.main_color = COLOR_HOS_BG;
|
||||
//bg.body.main_color = LV_COLOR_BLACK;
|
||||
bg.body.main_color = COLOR_BG;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.radius = 0;
|
||||
bg.body.empty = 1;
|
||||
|
||||
lv_style_copy(&panel, &def);
|
||||
panel.body.radius = DEF_RADIUS;
|
||||
panel.body.main_color = COLOR_HOS_BG;
|
||||
panel.body.grad_color = COLOR_HOS_BG;
|
||||
panel.body.main_color = COLOR_BG;
|
||||
panel.body.grad_color = COLOR_BG;
|
||||
panel.body.border.width = 1;
|
||||
panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
|
||||
panel.body.border.color = COLOR_LIGHT_BORDER;
|
||||
panel.body.border.opa = LV_OPA_COVER;
|
||||
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
||||
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
|
@ -129,7 +132,7 @@ static void btn_init(void)
|
|||
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
||||
|
||||
lv_style_copy(&rel, &def);
|
||||
rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.main_color = COLOR_BG_LIGHT;
|
||||
rel.body.grad_color = rel.body.main_color;
|
||||
rel.body.radius = 6;
|
||||
rel.body.padding.hor = LV_DPI / 3;
|
||||
|
@ -139,7 +142,7 @@ static void btn_init(void)
|
|||
rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
rel.body.shadow.width = 6;
|
||||
rel.body.border.width = 0;
|
||||
rel.body.border.color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.border.color = COLOR_BG_LIGHT;
|
||||
rel.body.border.part = LV_BORDER_FULL;
|
||||
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
||||
|
||||
|
@ -162,7 +165,7 @@ static void btn_init(void)
|
|||
tgl_pr.body.shadow.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &rel);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
//ina.body.shadow.width = 0;
|
||||
ina.text.color = LV_COLOR_HEX(0x888888);
|
||||
|
@ -207,7 +210,7 @@ static void img_init(void)
|
|||
img_light.image.intense = LV_OPA_80;
|
||||
|
||||
lv_style_copy(&img_dark, &def);
|
||||
img_dark.image.color = COLOR_HOS_BG_DARKER;
|
||||
img_dark.image.color = COLOR_BG_DARKER;
|
||||
img_dark.image.intense = LV_OPA_80;
|
||||
|
||||
|
||||
|
@ -250,7 +253,7 @@ static void bar_init(void)
|
|||
static lv_style_t bar_bg, bar_indic;
|
||||
|
||||
lv_style_copy(&bar_bg, &def);
|
||||
bar_bg.body.main_color = COLOR_HOS_LIGHT_BORDER;
|
||||
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
|
||||
bar_bg.body.grad_color = bar_bg.body.main_color;
|
||||
bar_bg.body.radius = 3;
|
||||
bar_bg.body.border.width = 0;
|
||||
|
@ -536,9 +539,9 @@ static void mbox_init(void)
|
|||
static lv_style_t bg;
|
||||
|
||||
lv_style_copy(&bg, theme.panel);
|
||||
bg.body.main_color = LV_COLOR_HEX(0x464646);
|
||||
bg.body.main_color = COLOR_BG_LIGHTER;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.shadow.color = COLOR_HOS_BG;
|
||||
bg.body.shadow.color = COLOR_BG;
|
||||
bg.body.shadow.type = LV_SHADOW_FULL;
|
||||
bg.body.shadow.width = 8;
|
||||
|
||||
|
@ -628,7 +631,7 @@ static void list_init(void)
|
|||
// pr.text.font = _font;
|
||||
|
||||
lv_style_copy(&tgl_rel, &pr);
|
||||
tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_rel.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_rel.body.grad_color = tgl_rel.body.main_color;
|
||||
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
|
||||
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
||||
|
@ -639,7 +642,7 @@ static void list_init(void)
|
|||
tgl_pr.body.border.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &pr);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
|
||||
theme.list.sb = &sb;
|
||||
|
@ -667,7 +670,7 @@ static void ddlist_init(void)
|
|||
bg.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&sel, &bg);
|
||||
sel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
sel.body.main_color = COLOR_BG_LIGHT;
|
||||
sel.body.grad_color = sel.body.main_color;
|
||||
|
||||
theme.ddlist.bg = &bg;
|
||||
|
@ -713,7 +716,7 @@ static void tabview_init(void)
|
|||
indic.body.opa = LV_OPA_0;
|
||||
|
||||
lv_style_copy(&btn_bg, &def);
|
||||
btn_bg.body.main_color = COLOR_HOS_BG;
|
||||
btn_bg.body.main_color = COLOR_BG;
|
||||
btn_bg.body.grad_color = btn_bg.body.main_color;
|
||||
btn_bg.body.radius = 0;
|
||||
btn_bg.body.empty = 1;
|
||||
|
@ -734,7 +737,7 @@ static void tabview_init(void)
|
|||
rel.text.font = _font;
|
||||
|
||||
lv_style_copy(&pr, &def);
|
||||
pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
pr.body.main_color = COLOR_BG_LIGHT;
|
||||
pr.body.grad_color = pr.body.main_color;
|
||||
pr.body.border.width = 0;
|
||||
pr.body.empty = 0;
|
||||
|
@ -750,7 +753,7 @@ static void tabview_init(void)
|
|||
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&tgl_pr, &def);
|
||||
tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_pr.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||
tgl_pr.body.border.width = 0;
|
||||
tgl_pr.body.empty = 0;
|
||||
|
@ -797,7 +800,7 @@ static void win_init(void)
|
|||
static lv_style_t header, rel, pr;
|
||||
|
||||
lv_style_copy(&header, &def);
|
||||
header.body.main_color = COLOR_HOS_BG;
|
||||
header.body.main_color = COLOR_BG;
|
||||
header.body.grad_color = header.body.main_color;
|
||||
header.body.radius = 0;
|
||||
header.body.border.width = 0;
|
||||
|
@ -843,10 +846,11 @@ static void win_init(void)
|
|||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
|
||||
{
|
||||
if(font == NULL) font = LV_FONT_DEFAULT;
|
||||
|
||||
theme_bg_color = bg_color;
|
||||
_hue = hue;
|
||||
_font = font;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -35,6 +35,14 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
|
||||
#define COLOR_HOS_BG_BASE_BLACK 0x000000
|
||||
|
||||
#define COLOR_HOS_BG_DARKER 0x1B1B1B
|
||||
#define COLOR_HOS_BG_DARK 0x222222
|
||||
#define COLOR_HOS_BG 0x2D2D2D
|
||||
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
|
||||
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
@ -44,13 +52,15 @@ extern "C" {
|
|||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
extern uint32_t theme_bg_color;
|
||||
|
||||
/**
|
||||
* Initialize the material theme
|
||||
* @param hue [0..360] hue value from HSV color space to define the theme's base color
|
||||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
|
||||
|
||||
/**
|
||||
* Get a pointer to the theme
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* arch/arm/mach-tegra/tegra21_emc.h
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019-2020, CTCaer.
|
||||
* Copyright (c) 2019-2024, CTCaer.
|
||||
*
|
||||
* 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
|
||||
|
@ -23,6 +23,7 @@
|
|||
#ifndef _EMC_H_
|
||||
#define _EMC_H_
|
||||
|
||||
#define EMC_INTSTATUS 0x0
|
||||
#define EMC_DBG 0x8
|
||||
#define EMC_CFG 0xC
|
||||
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
||||
|
@ -698,6 +699,8 @@
|
|||
|
||||
typedef enum _emc_mr_t
|
||||
{
|
||||
MR0_FEAT = 0,
|
||||
MR4_TEMP = 4,
|
||||
MR5_MAN_ID = 5,
|
||||
MR6_REV_ID1 = 6,
|
||||
MR7_REV_ID2 = 7,
|
||||
|
@ -710,7 +713,7 @@ enum
|
|||
EMC_CHAN1 = 1
|
||||
};
|
||||
|
||||
typedef struct _emc_mr_data_t
|
||||
typedef struct _emc_mr_chip_data_t
|
||||
{
|
||||
// Device 0.
|
||||
u8 rank0_ch0;
|
||||
|
@ -719,6 +722,12 @@ typedef struct _emc_mr_data_t
|
|||
// Device 1.
|
||||
u8 rank1_ch0;
|
||||
u8 rank1_ch1;
|
||||
} emc_mr_chip_data_t;
|
||||
|
||||
typedef struct _emc_mr_data_t
|
||||
{
|
||||
emc_mr_chip_data_t chip0;
|
||||
emc_mr_chip_data_t chip1;
|
||||
} emc_mr_data_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,33 +19,44 @@
|
|||
#include "heap.h"
|
||||
#include <gfx_utils.h>
|
||||
|
||||
static void _heap_create(heap_t *heap, u32 start)
|
||||
heap_t _heap;
|
||||
|
||||
static void _heap_create(void *start)
|
||||
{
|
||||
heap->start = start;
|
||||
heap->first = NULL;
|
||||
_heap.start = start;
|
||||
_heap.first = NULL;
|
||||
_heap.last = NULL;
|
||||
}
|
||||
|
||||
// Node info is before node address.
|
||||
static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
static void *_heap_alloc(u32 size)
|
||||
{
|
||||
hnode_t *node, *new_node;
|
||||
|
||||
// Align to cache line size.
|
||||
size = ALIGN(size, sizeof(hnode_t));
|
||||
|
||||
if (!heap->first)
|
||||
// First allocation.
|
||||
if (!_heap.first)
|
||||
{
|
||||
node = (hnode_t *)heap->start;
|
||||
node = (hnode_t *)_heap.start;
|
||||
node->used = 1;
|
||||
node->size = size;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
heap->first = node;
|
||||
|
||||
return (u32)node + sizeof(hnode_t);
|
||||
_heap.first = node;
|
||||
_heap.last = node;
|
||||
|
||||
return (void *)node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
node = heap->first;
|
||||
#ifdef BDK_MALLOC_NO_DEFRAG
|
||||
// Get the last allocated block.
|
||||
node = _heap.last;
|
||||
#else
|
||||
// Get first block and find the first available one.
|
||||
node = _heap.first;
|
||||
while (true)
|
||||
{
|
||||
// Check if there's available unused node.
|
||||
|
@ -53,7 +64,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
{
|
||||
// Size and offset of the new unused node.
|
||||
u32 new_size = node->size - size;
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + size);
|
||||
|
||||
// If there's aligned unused space from the old node,
|
||||
// create a new one and set the leftover size.
|
||||
|
@ -76,7 +87,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
node->size = size;
|
||||
node->used = 1;
|
||||
|
||||
return (u32)node + sizeof(hnode_t);
|
||||
return (void *)node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
// No unused node found, try the next one.
|
||||
|
@ -85,23 +96,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
else
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// No unused node found, create a new one.
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
|
||||
new_node->used = 1;
|
||||
new_node->size = size;
|
||||
new_node->prev = node;
|
||||
new_node->next = NULL;
|
||||
node->next = new_node;
|
||||
|
||||
return (u32)new_node + sizeof(hnode_t);
|
||||
node->next = new_node;
|
||||
_heap.last = new_node;
|
||||
|
||||
return (void *)new_node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
static void _heap_free(heap_t *heap, u32 addr)
|
||||
static void _heap_free(void *addr)
|
||||
{
|
||||
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
|
||||
node->used = 0;
|
||||
node = heap->first;
|
||||
node = _heap.first;
|
||||
|
||||
#ifndef BDK_MALLOC_NO_DEFRAG
|
||||
// Do simple defragmentation on next blocks.
|
||||
while (node)
|
||||
{
|
||||
if (!node->used)
|
||||
|
@ -117,36 +134,42 @@ static void _heap_free(heap_t *heap, u32 addr)
|
|||
}
|
||||
node = node->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
heap_t _heap;
|
||||
|
||||
void heap_init(u32 base)
|
||||
void heap_init(void *base)
|
||||
{
|
||||
_heap_create(&_heap, base);
|
||||
_heap_create(base);
|
||||
}
|
||||
|
||||
void heap_copy(heap_t *heap)
|
||||
void heap_set(heap_t *heap)
|
||||
{
|
||||
memcpy(&_heap, heap, sizeof(heap_t));
|
||||
}
|
||||
|
||||
void *malloc(u32 size)
|
||||
{
|
||||
return (void *)_heap_alloc(&_heap, size);
|
||||
return _heap_alloc(size);
|
||||
}
|
||||
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||
void *res = (void *)_heap_alloc(num * size);
|
||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
void *zalloc(u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(size);
|
||||
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
void free(void *buf)
|
||||
{
|
||||
if ((u32)buf >= _heap.start)
|
||||
_heap_free(&_heap, (u32)buf);
|
||||
if (buf >= _heap.start)
|
||||
_heap_free(buf);
|
||||
}
|
||||
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
|
@ -158,7 +181,10 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
|||
while (true)
|
||||
{
|
||||
if (node->used)
|
||||
{
|
||||
mon->nodes_used++;
|
||||
mon->used += node->size + sizeof(hnode_t);
|
||||
}
|
||||
else
|
||||
mon->total += node->size + sizeof(hnode_t);
|
||||
|
||||
|
@ -174,4 +200,5 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
|||
break;
|
||||
}
|
||||
mon->total += mon->used;
|
||||
mon->nodes_total = count;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -31,20 +31,24 @@ typedef struct _hnode
|
|||
|
||||
typedef struct _heap
|
||||
{
|
||||
u32 start;
|
||||
void *start;
|
||||
hnode_t *first;
|
||||
hnode_t *last;
|
||||
} heap_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 total;
|
||||
u32 used;
|
||||
u32 total;
|
||||
u32 used;
|
||||
u32 nodes_total;
|
||||
u32 nodes_used;
|
||||
} heap_monitor_t;
|
||||
|
||||
void heap_init(u32 base);
|
||||
void heap_copy(heap_t *heap);
|
||||
void heap_init(void *base);
|
||||
void heap_set(heap_t *heap);
|
||||
void *malloc(u32 size);
|
||||
void *calloc(u32 num, u32 size);
|
||||
void *zalloc(u32 size);
|
||||
void free(void *buf);
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
|
||||
|
||||
|
|
138
bdk/mem/mc.c
138
bdk/mem/mc.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,12 +15,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <mem/mc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
|
||||
void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
|
||||
{
|
||||
MC(MC_SEC_CARVEOUT_BOM) = bom;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
|
||||
|
@ -30,105 +31,56 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
|
|||
|
||||
void mc_config_carveout()
|
||||
{
|
||||
// Enable ACR GSR3.
|
||||
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
|
||||
|
||||
// Configure TSEC carveout @ 0x90000000, 1MB.
|
||||
//mc_config_tsec_carveout(0x90000000, 1, false);
|
||||
mc_config_tsec_carveout(0, 0, true);
|
||||
// Configure TZDRAM carveout @ 0x90000000, 1MB.
|
||||
//mc_config_tzdram_carveout(0x90000000, 1, false);
|
||||
mc_config_tzdram_carveout(0, 0, true);
|
||||
|
||||
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
|
||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(0) |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
|
||||
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
|
||||
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||
SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_WR_NS;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
|
||||
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||
SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_WR_NS;
|
||||
}
|
||||
|
||||
void mc_enable_ahb_redirect()
|
||||
{
|
||||
// Enable ARC_CLK_OVR_ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000;
|
||||
//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
|
||||
MC(MC_IRAM_BOM) = 0x40000000;
|
||||
MC(MC_IRAM_TOM) = 0x4003F000;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
||||
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
||||
MC(MC_IRAM_BOM) = IRAM_BASE;
|
||||
MC(MC_IRAM_TOM) = DRAM_START; // Default is only IRAM: 0x4003F000.
|
||||
}
|
||||
|
||||
void mc_disable_ahb_redirect()
|
||||
|
@ -136,24 +88,36 @@ void mc_disable_ahb_redirect()
|
|||
MC(MC_IRAM_BOM) = 0xFFFFF000;
|
||||
MC(MC_IRAM_TOM) = 0;
|
||||
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
||||
//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
|
||||
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
||||
// Disable ARC_CLK_OVR_ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
||||
}
|
||||
|
||||
bool mc_client_has_access(void *address)
|
||||
{
|
||||
// Check if address is in DRAM or if arbitration for IRAM is enabled.
|
||||
if ((u32)address >= DRAM_START)
|
||||
return true; // Access by default.
|
||||
else if ((u32)address >= IRAM_BASE && MC(MC_IRAM_BOM) == IRAM_BASE)
|
||||
return true; // Access by AHB arbitration.
|
||||
|
||||
// No access to address space.
|
||||
return false;
|
||||
}
|
||||
|
||||
void mc_enable()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
|
||||
// Enable memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_EMC)) | BIT(CLK_H_EMC);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_MEM)) | BIT(CLK_H_MEM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & ~BIT(CLK_X_EMC_DLL)) | BIT(CLK_X_EMC_DLL);
|
||||
// Clear clock resets for memory.
|
||||
// Reset EMC source to PLLP.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
|
||||
// Enable and clear reset for memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
usleep(5);
|
||||
|
||||
//#ifdef CONFIG_ENABLE_AHB_REDIRECT
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
mc_enable_ahb_redirect();
|
||||
#else
|
||||
mc_disable_ahb_redirect();
|
||||
//mc_enable_ahb_redirect();
|
||||
//#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ void mc_config_carveout();
|
|||
void mc_config_carveout_finalize();
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_disable_ahb_redirect();
|
||||
bool mc_client_has_access(void *address);
|
||||
void mc_enable();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2014, NVIDIA Corporation.
|
||||
* Copyright (c) 2018-2023, CTCaer
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
|
@ -14,6 +15,22 @@
|
|||
#ifndef _MC_T210_H_
|
||||
#define _MC_T210_H_
|
||||
|
||||
/*! MC SMMU registers */
|
||||
#define MC_SMMU_CONFIG 0x10
|
||||
#define MC_SMMU_TLB_CONFIG 0x14
|
||||
#define MC_SMMU_PTC_CONFIG 0x18
|
||||
#define MC_SMMU_PTB_ASID 0x1c
|
||||
#define MC_SMMU_PTB_DATA 0x20
|
||||
#define MC_SMMU_TLB_FLUSH 0x30
|
||||
#define MC_SMMU_PTC_FLUSH 0x34
|
||||
#define MC_SMMU_ASID_SECURITY 0x38
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
||||
|
||||
/*! MC General registers */
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
|
@ -464,11 +481,111 @@
|
|||
#define MC_UNTRANSLATED_REGION_CHECK 0x948
|
||||
#define MC_DA_CONFIG0 0x9dc
|
||||
|
||||
/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */
|
||||
#define SEC_CARVEOUT_CA0_R_PTCR BIT(0)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0B BIT(3)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0BB BIT(4)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0C BIT(5)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0CB BIT(6)
|
||||
#define SEC_CARVEOUT_CA0_R_AFI BIT(14)
|
||||
#define SEC_CARVEOUT_CA0_R_BPMP_C BIT(15)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAYHC BIT(16)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAYHCB BIT(17)
|
||||
#define SEC_CARVEOUT_CA0_R_HDA BIT(21)
|
||||
#define SEC_CARVEOUT_CA0_R_HOST1XDMA BIT(22)
|
||||
#define SEC_CARVEOUT_CA0_R_HOST1X BIT(23)
|
||||
#define SEC_CARVEOUT_CA0_R_NVENC BIT(28)
|
||||
#define SEC_CARVEOUT_CA0_R_PPCSAHBDMA BIT(29)
|
||||
#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30)
|
||||
#define SEC_CARVEOUT_CA0_R_SATAR BIT(31)
|
||||
|
||||
/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */
|
||||
#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2)
|
||||
#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3)
|
||||
#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4)
|
||||
#define SEC_CARVEOUT_CA1_R_VDETPE BIT(5)
|
||||
#define SEC_CARVEOUT_CA1_R_CCPLEXLP_C BIT(6)
|
||||
#define SEC_CARVEOUT_CA1_R_CCPLEX_C BIT(7)
|
||||
#define SEC_CARVEOUT_CA1_W_NVENC BIT(11)
|
||||
#define SEC_CARVEOUT_CA1_W_AFI BIT(17)
|
||||
#define SEC_CARVEOUT_CA1_W_BPMP_C BIT(18)
|
||||
#define SEC_CARVEOUT_CA1_W_HDA BIT(21)
|
||||
#define SEC_CARVEOUT_CA1_W_HOST1X BIT(22)
|
||||
#define SEC_CARVEOUT_CA1_W_CCPLEXLP_C BIT(24)
|
||||
#define SEC_CARVEOUT_CA1_W_CCPLEX_C BIT(25)
|
||||
#define SEC_CARVEOUT_CA1_W_PPCSAHBDMA BIT(27)
|
||||
#define SEC_CARVEOUT_CA1_W_PPCSAHBSLV BIT(28)
|
||||
#define SEC_CARVEOUT_CA1_W_SATA BIT(29)
|
||||
#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30)
|
||||
#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31)
|
||||
|
||||
/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */
|
||||
#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0)
|
||||
#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1)
|
||||
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
|
||||
#define SEC_CARVEOUT_CA2_W_ISPWA BIT(6)
|
||||
#define SEC_CARVEOUT_CA2_W_ISPWB BIT(7)
|
||||
#define SEC_CARVEOUT_CA2_R_XUSB_HOST BIT(10)
|
||||
#define SEC_CARVEOUT_CA2_W_XUSB_HOST BIT(11)
|
||||
#define SEC_CARVEOUT_CA2_R_XUSB_DEV BIT(12)
|
||||
#define SEC_CARVEOUT_CA2_W_XUSB_DEV BIT(13)
|
||||
#define SEC_CARVEOUT_CA2_R_SE2 BIT(14)
|
||||
#define SEC_CARVEOUT_CA2_W_SE2 BIT(16)
|
||||
#define SEC_CARVEOUT_CA2_R_TSEC BIT(20)
|
||||
#define SEC_CARVEOUT_CA2_W_TSEC BIT(21)
|
||||
#define SEC_CARVEOUT_CA2_R_ADSP_SC BIT(22)
|
||||
#define SEC_CARVEOUT_CA2_W_ADSP_SC BIT(23)
|
||||
#define SEC_CARVEOUT_CA2_R_GPU BIT(24)
|
||||
#define SEC_CARVEOUT_CA2_W_GPU BIT(25)
|
||||
#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26)
|
||||
|
||||
/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCAB BIT(3)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCA BIT(4)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCAA BIT(5)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMC BIT(6)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCAB BIT(7)
|
||||
#define SEC_CARVEOUT_CA3_R_VIC BIT(12)
|
||||
#define SEC_CARVEOUT_CA3_W_VIC BIT(13)
|
||||
#define SEC_CARVEOUT_CA3_W_VIW BIT(18)
|
||||
#define SEC_CARVEOUT_CA3_R_DISPLAYD BIT(19)
|
||||
#define SEC_CARVEOUT_CA3_R_NVDEC BIT(24)
|
||||
#define SEC_CARVEOUT_CA3_W_NVDEC BIT(25)
|
||||
#define SEC_CARVEOUT_CA3_R_APE BIT(26)
|
||||
#define SEC_CARVEOUT_CA3_W_APE BIT(27)
|
||||
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
|
||||
#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31)
|
||||
|
||||
/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */
|
||||
#define SEC_CARVEOUT_CA4_R_SE BIT(0)
|
||||
#define SEC_CARVEOUT_CA4_W_SE BIT(1)
|
||||
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)
|
||||
#define SEC_CARVEOUT_CA4_W_AXIAP BIT(3)
|
||||
#define SEC_CARVEOUT_CA4_R_ETR BIT(4)
|
||||
#define SEC_CARVEOUT_CA4_W_ETR BIT(5)
|
||||
#define SEC_CARVEOUT_CA4_R_TSECB BIT(6)
|
||||
#define SEC_CARVEOUT_CA4_W_TSECB BIT(7)
|
||||
#define SEC_CARVEOUT_CA4_R_GPU2 BIT(8)
|
||||
#define SEC_CARVEOUT_CA4_W_GPU2 BIT(9)
|
||||
|
||||
// MC_VIDEO_PROTECT_REG_CTRL
|
||||
#define VPR_LOCK_MODE_SHIFT 0
|
||||
#define VPR_CTRL_UNLOCKED (0 << VPR_LOCK_MODE_SHIFT)
|
||||
#define VPR_CTRL_LOCKED (1 << VPR_LOCK_MODE_SHIFT)
|
||||
#define VPR_PROTECT_MODE_SHIFT 1
|
||||
#define SEC_CTRL_SECURE (0 << VPR_PROTECT_MODE_SHIFT)
|
||||
#define VPR_CTRL_TZ_SECURE (1 << VPR_PROTECT_MODE_SHIFT)
|
||||
|
||||
// MC_SECURITY_CARVEOUTX_CFG0
|
||||
// Mode of LOCK_MODE.
|
||||
#define PROTECT_MODE_SHIFT 0
|
||||
#define SEC_CARVEOUT_CFG_SECURE (0 << PROTECT_MODE_SHIFT0)
|
||||
#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT0)
|
||||
#define SEC_CARVEOUT_CFG_ALL_SECURE (0 << PROTECT_MODE_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT)
|
||||
// Enables PROTECT_MODE.
|
||||
#define LOCK_MODE_SHIFT 1
|
||||
#define SEC_CARVEOUT_CFG_UNLOCKED (0 << LOCK_MODE_SHIFT)
|
||||
|
@ -479,30 +596,31 @@
|
|||
#define SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY (1 << ADDRESS_TYPE_SHIFT)
|
||||
|
||||
#define READ_ACCESS_LEVEL_SHIFT 3
|
||||
#define SEC_CARVEOUT_CFG_RD_ALL (1 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_UNK (2 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_NS (1 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_SEC (2 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_FALCON_LS (4 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_FALCON_HS (8 << READ_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define WRITE_ACCESS_LEVEL_SHIFT 7
|
||||
#define SEC_CARVEOUT_CFG_WR_ALL (1 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_UNK (2 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_NS (1 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_SEC (2 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_FALCON_LS (4 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_FALCON_HS (8 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define SEC_CARVEOUT_CFG_APERTURE_ID_MASK (3 << 11)
|
||||
#define SEC_CARVEOUT_CFG_APERTURE_ID(id) ((id) << 11)
|
||||
|
||||
#define DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT 14
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L0 (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L1 (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L2 (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L3 (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_NS (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_SEC (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_LS (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_HS (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT 18
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L0 (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L1 (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L2 (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L3 (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_NS (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_SEC (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_LS (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_HS (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU BIT(22)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,21 +19,26 @@
|
|||
|
||||
#include "minerva.h"
|
||||
|
||||
#include <soc/clock.h>
|
||||
#include <ianos/ianos.h>
|
||||
#include <mem/emc.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define TABLE_FREQ_KHZ_OFFSET 0x40
|
||||
#define TABLE_LA_REGS_T210_OFFSET 0x1284
|
||||
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
|
||||
#define LA_SDMMC1_INDEX 6
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
|
||||
u32 minerva_init()
|
||||
{
|
||||
u32 curr_ram_idx = 0;
|
||||
u32 tbl_idx = 0;
|
||||
|
||||
minerva_cfg = NULL;
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
@ -42,7 +47,7 @@ u32 minerva_init()
|
|||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
return 0;
|
||||
|
||||
#ifdef NYX
|
||||
#ifdef BDK_MINERVA_CFG_FROM_RAM
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
|
||||
|
||||
|
@ -60,7 +65,7 @@ u32 minerva_init()
|
|||
mtc_config_t mtc_tmp;
|
||||
|
||||
mtc_tmp.mtc_table = mtc_cfg->mtc_table;
|
||||
mtc_tmp.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||
mtc_tmp.sdram_id = fuse_read_dramid(false);
|
||||
mtc_tmp.init_done = MTC_NEW_MAGIC;
|
||||
|
||||
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp);
|
||||
|
@ -81,7 +86,7 @@ u32 minerva_init()
|
|||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
|
||||
|
||||
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||
mtc_cfg->sdram_id = fuse_read_dramid(false);
|
||||
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
|
||||
|
||||
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
|
@ -97,28 +102,29 @@ u32 minerva_init()
|
|||
return 1;
|
||||
|
||||
// Get current frequency
|
||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
|
||||
{
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
|
||||
break;
|
||||
}
|
||||
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
|
||||
mtc_cfg->rate_to = 204000;
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
|
||||
mtc_cfg->rate_to = FREQ_204;
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = 800000;
|
||||
mtc_cfg->rate_to = FREQ_800;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
mtc_cfg->rate_to = FREQ_1600;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
// FSP WAR.
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
mtc_cfg->rate_to = 800000;
|
||||
mtc_cfg->rate_to = FREQ_800;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
// Switch to max.
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
mtc_cfg->rate_to = FREQ_1600;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
return 0;
|
||||
|
@ -129,6 +135,7 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||
if (!minerva_cfg)
|
||||
return;
|
||||
|
||||
// Check if requested frequency is different. Do not allow otherwise because it will hang.
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
if (mtc_cfg->rate_from != freq)
|
||||
{
|
||||
|
@ -138,6 +145,110 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||
}
|
||||
}
|
||||
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||
{
|
||||
|
||||
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
|
||||
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
|
||||
|
||||
// Adjust SDMMC1 latency allowance.
|
||||
switch (freq)
|
||||
{
|
||||
case 204000:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
|
||||
break;
|
||||
case 408000:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
|
||||
break;
|
||||
default:
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void minerva_prep_boot_freq()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Check if there's RAM OC. If not exit.
|
||||
if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
return;
|
||||
|
||||
// FSP WAR.
|
||||
minerva_change_freq(FREQ_204);
|
||||
// Scale down to 800 MHz boot freq.
|
||||
minerva_change_freq(FREQ_800);
|
||||
}
|
||||
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Program SDMMC LA regs.
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
|
||||
// Add OC frequency.
|
||||
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
|
||||
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
|
||||
sizeof(emc_table_t));
|
||||
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
||||
mtc_cfg->table_entries++;
|
||||
}
|
||||
|
||||
// Trim table.
|
||||
int entries = 0;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
|
||||
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||
if (rate == FREQ_204 ||
|
||||
rate == FREQ_408 ||
|
||||
rate == FREQ_800 ||
|
||||
rate >= FREQ_1333)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
mtc_cfg->table_entries = entries;
|
||||
|
||||
// Set init frequency.
|
||||
minerva_change_freq(FREQ_204);
|
||||
|
||||
// Train the rest of the frequencies.
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
// Skip already trained frequencies and OC freq (Arachne handles it).
|
||||
if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
|
||||
continue;
|
||||
|
||||
// Train frequency.
|
||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
}
|
||||
|
||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
||||
if (fsp_opwr_disabled)
|
||||
minerva_change_freq(FREQ_1333);
|
||||
minerva_change_freq(FREQ_800);
|
||||
|
||||
// Do not let other mtc ops.
|
||||
mtc_cfg->init_done = 0;
|
||||
}
|
||||
|
||||
void minerva_periodic_training()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
|
@ -149,4 +260,22 @@ void minerva_periodic_training()
|
|||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emc_table_t *minerva_get_mtc_table()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return NULL;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->mtc_table;
|
||||
}
|
||||
|
||||
int minerva_get_mtc_table_entries()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return 0;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->table_entries;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -27,8 +27,8 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
s32 rate_to;
|
||||
s32 rate_from;
|
||||
u32 rate_to;
|
||||
u32 rate_from;
|
||||
emc_table_t *mtc_table;
|
||||
u32 table_entries;
|
||||
emc_table_t *current_emc_table;
|
||||
|
@ -38,7 +38,7 @@ typedef struct
|
|||
bool emc_2X_clk_src_is_pllmb;
|
||||
bool fsp_for_src_freq;
|
||||
bool train_ram_patterns;
|
||||
bool init_done;
|
||||
u32 init_done;
|
||||
} mtc_config_t;
|
||||
|
||||
enum train_mode_t
|
||||
|
@ -53,13 +53,20 @@ enum train_mode_t
|
|||
typedef enum
|
||||
{
|
||||
FREQ_204 = 204000,
|
||||
FREQ_408 = 408000,
|
||||
FREQ_800 = 800000,
|
||||
FREQ_1333 = 1331200,
|
||||
FREQ_1600 = 1600000
|
||||
} minerva_freq_t;
|
||||
|
||||
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
u32 minerva_init();
|
||||
void minerva_change_freq(minerva_freq_t freq);
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01);
|
||||
void minerva_prep_boot_freq();
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom);
|
||||
void minerva_periodic_training();
|
||||
emc_table_t *minerva_get_mtc_table();
|
||||
int minerva_get_mtc_table_entries();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -481,7 +481,8 @@ typedef struct
|
|||
u32 rate_khz;
|
||||
u32 min_volt;
|
||||
u32 gpu_min_volt;
|
||||
char clock_src[32];
|
||||
char clock_src[28];
|
||||
u32 opt_custom;
|
||||
u32 clk_src_emc;
|
||||
u32 needs_training;
|
||||
u32 training_pattern;
|
||||
|
|
1417
bdk/mem/sdram.c
1417
bdk/mem/sdram.c
File diff suppressed because it is too large
Load diff
132
bdk/mem/sdram.h
132
bdk/mem/sdram.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -23,73 +23,119 @@
|
|||
/*
|
||||
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
||||
*
|
||||
* 40.8 MHz: 0.61 GiB/s
|
||||
* 68.0 MHz: 1.01 GiB/s
|
||||
* 102.0 MHz: 1.52 GiB/s
|
||||
* 204.0 MHz: 3.04 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
|
||||
* 408.0 MHz: 6.08 GiB/s
|
||||
* 665.6 MHz: 9.92 GiB/s
|
||||
* 800.0 MHz: 11.92 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
||||
* 1065.6 MHz: 15.89 GiB/s
|
||||
* 1331.2 MHz: 19.84 GiB/s
|
||||
* 1600.0 MHz: 23.84 GiB/s <-- Tegra X1 Official Max Frequency
|
||||
* 1862.4 MHz: 27.75 GiB/s <-- Tegra X1+ Official Max Frequency
|
||||
* 2131.2 MHz: 31.76 GiB/s
|
||||
* Note: Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
|
||||
* Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
|
||||
* Configurations supported: 1x32, 2x32, 1x64.
|
||||
* x64 ram modules can be used by combining the 2 32-bit channels into one.
|
||||
*
|
||||
* Note: BWbits = Hz x bus width x channels = Hz x 64 x 2.
|
||||
* 204.0 MHz: 3.04 <-- Tegra X1/X1+ Init/SC7 Frequency
|
||||
* 408.0 MHz: 6.08
|
||||
* 665.6 MHz: 9.92
|
||||
* 800.0 MHz: 11.92 <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
||||
* 1065.6 MHz: 15.89
|
||||
* 1331.2 MHz: 19.84
|
||||
* 1600.0 MHz: 23.84
|
||||
* 1862.4 MHz: 27.75 <-- Tegra X1 Official Max Frequency
|
||||
* 2131.2 MHz: 31.76 <-- Tegra X1+ Official Max Frequency. Not all regs have support for > 2046 MHz.
|
||||
*/
|
||||
|
||||
enum sdram_ids_erista
|
||||
{
|
||||
// LPDDR4 3200Mbps.
|
||||
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
|
||||
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
|
||||
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2,
|
||||
LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3,
|
||||
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
|
||||
LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5,
|
||||
LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6,
|
||||
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
|
||||
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
|
||||
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
|
||||
|
||||
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, // Die-C. (2y-01).
|
||||
|
||||
/*
|
||||
* Custom hekate/L4T supported 8GB. 7 dram id can be easily applied in fuses.
|
||||
*
|
||||
* 4GB modules:
|
||||
* Samsung K4FBE3D4HM-MGCH/CJ/CL. MG/TF/GF/TH/GH: Package + Temperature.
|
||||
* Hynix H9HCNNNCPUMLXR-NME/NEE/NEI. E/I: Temperature.
|
||||
* Hynix H54G56BYYVX046/QX046/PX046. V/Q/P: Package + Temperature.
|
||||
*/
|
||||
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // XX: CH/CJ/CL.
|
||||
};
|
||||
|
||||
enum sdram_ids_mariko
|
||||
{
|
||||
/*
|
||||
* Nintendo Switch LPDRR4X generations:
|
||||
* - 1x nm are 1st-gen
|
||||
* - 1y nm are 2nd-gen
|
||||
* - 1z/a nm are 3rd-gen
|
||||
*/
|
||||
|
||||
// LPDDR4X 4266Mbps.
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
|
||||
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
|
||||
|
||||
// LPDDR4X 3733Mbps.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7,
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8,
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9,
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10,
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps.
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
|
||||
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12,
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13,
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14,
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps.
|
||||
// LPDDR4X 4266Mbps.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03).
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03).
|
||||
|
||||
// LPDDR4X 4266Mbps?
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16,
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. (1z-01). 40% lp.
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
|
||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. (1z-01). 40% lp.
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X = 17,
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X = 18,
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X = 19,
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
|
||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20,
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21,
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
|
||||
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
|
||||
|
||||
LPDDR4X_SDS_4GB_SAMSUNG_1Y_A = 22,
|
||||
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
|
||||
|
||||
LPDDR4X_SDS_8GB_SAMSUNG_1Y_X = 23,
|
||||
LPDDR4X_SDS_4GB_SAMSUNG_1Y_X = 24,
|
||||
// Old naming scheme: H9HCNNNBKMCLXR-NEE
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
|
||||
LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
|
||||
|
||||
LPDDR4X_IOWA_4GB_MICRON_1Y_A = 25,
|
||||
LPDDR4X_HOAG_4GB_MICRON_1Y_A = 26,
|
||||
LPDDR4X_SDS_4GB_MICRON_1Y_A = 27
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
|
||||
};
|
||||
|
||||
enum sdram_codes_mariko
|
||||
{
|
||||
LPDDR4X_NO_PATCH = 0,
|
||||
LPDDR4X_UNUSED = 0,
|
||||
|
||||
// LPDDR4X_4GB_SAMSUNG_K4U6E3S4AM_MGCJ DRAM IDs: 08, 12.
|
||||
// LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLHR_NME DRAM IDs: 10, 14.
|
||||
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 1, // DRAM IDs: 09, 13.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
|
||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
|
||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 5, // DRAM IDs: 20, 21, 22.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
|
||||
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
|
||||
LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
|
||||
};
|
||||
|
||||
void sdram_init();
|
||||
void *sdram_get_params_patched();
|
||||
void *sdram_get_params_t210b01();
|
||||
void sdram_lp0_save_params(const void *params);
|
||||
void sdram_src_pllc(bool enable);
|
||||
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,8 +17,6 @@
|
|||
|
||||
#define DRAM_CFG_T210_SIZE 1896
|
||||
|
||||
#define DRAM_ID(x) BIT(x)
|
||||
|
||||
static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
/* Specifies the type of memory device */
|
||||
.memory_type = MEMORY_TYPE_LPDDR4,
|
||||
|
@ -97,7 +95,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
.emc_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
|
||||
.emc_adr_cfg = 0x00000001, // 2 Ranks.
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
|
@ -243,7 +241,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.emc_cfg_dig_dll = 0x002C00A0,
|
||||
.emc_cfg_dig_dll_1 = 0x00003701,
|
||||
.emc_cfg_dig_dll_period = 0x00008000,
|
||||
.emc_dev_select = 0x00000000, // Both devices.
|
||||
.emc_dev_select = 0x00000000, // Both Ranks.
|
||||
.emc_sel_dpd_ctrl = 0x00040008,
|
||||
|
||||
/* Pads trimmer delays */
|
||||
|
@ -406,7 +404,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.pmc_ddr_ctrl = 0x0007FF8B,
|
||||
.emc_acpd_control = 0x00000000,
|
||||
|
||||
.emc_swizzle_rank0_byte0 = 0x76543201,
|
||||
.emc_swizzle_rank0_byte0 = 0x76543201, // Overridden to 0x76543201 by spare6/7.
|
||||
.emc_swizzle_rank0_byte1 = 0x65324710,
|
||||
.emc_swizzle_rank0_byte2 = 0x25763410,
|
||||
.emc_swizzle_rank0_byte3 = 0x25673401,
|
||||
|
@ -436,9 +434,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.emc_dll_cfg0 = 0x1F13412F,
|
||||
.emc_dll_cfg1 = 0x00010014,
|
||||
|
||||
.emc_pmc_scratch1 = 0x4FAFFFFF,
|
||||
.emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
|
||||
.emc_pmc_scratch2 = 0x7FFFFFFF,
|
||||
.emc_pmc_scratch3 = 0x4006D70B,
|
||||
.emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
|
||||
|
||||
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
|
||||
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
|
||||
|
@ -454,7 +452,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.emc_pmacro_data_rx_term_mode = 0x00000010,
|
||||
.emc_pmacro_cmd_rx_term_mode = 0x00003000,
|
||||
.emc_pmacro_data_pad_tx_ctrl = 0x02000111,
|
||||
.emc_pmacro_common_pad_tx_ctrl = 0x00000008,
|
||||
.emc_pmacro_common_pad_tx_ctrl = 0x00000008, // Overridden to 0x0000000A by spare4/5.
|
||||
.emc_pmacro_cmd_pad_tx_ctrl = 0x0A000000,
|
||||
|
||||
.emc_cfg3 = 0x00000040,
|
||||
|
@ -490,9 +488,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.emc_pmacro_cmd_ctrl2 = 0x0A0A0A0A,
|
||||
|
||||
/* DRAM size information */
|
||||
.mc_emem_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00070302, // Density 512MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00070302, // Density 512MB.
|
||||
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00070302, // Chip 0 Density 512MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00070302, // Chip 1 Density 512MB.
|
||||
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
||||
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
||||
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
||||
|
@ -501,7 +499,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density.
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||
|
||||
/* MC arbitration configuration */
|
||||
.mc_emem_arb_cfg = 0x08000001,
|
||||
|
@ -543,13 +541,19 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
||||
.mc_video_protect_vpr_override1 = 0x00001ED3,
|
||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343. New: 0xE4FACB43. + TSEC, NVENC.
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
|
||||
.mc_video_protect_vpr_override1 = 0x0000FED3, // Default: 0x00001ED3. New: 0x0000FED3. + TSECB, TSEC1, TSECB1.
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
|
||||
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
|
||||
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
|
||||
.mc_video_protect_write_access = 0x00000000,
|
||||
.mc_sec_carveout_protect_write_access = 0x00000000,
|
||||
|
||||
|
@ -644,48 +648,27 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.mc_mts_carveout_reg_ctrl = 0x00000000
|
||||
};
|
||||
|
||||
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
|
||||
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
|
||||
// Hynix timing config.
|
||||
{ 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w.
|
||||
{ 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra.
|
||||
{ 0x80000000, 92, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_width.
|
||||
{ 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
|
||||
{ 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
|
||||
{ 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
|
||||
{ 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
|
||||
{ 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
|
||||
{ 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
|
||||
{ 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
|
||||
|
||||
// Samsung 6GB density config.
|
||||
{ 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
|
||||
{ 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
|
||||
{ 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
|
||||
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
|
||||
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
|
||||
{ 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
|
||||
|
||||
#ifdef CONFIG_SDRAM_COPPER_SUPPORT
|
||||
// Copper prototype Samsung/Hynix/Micron timing configs.
|
||||
{ 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
|
||||
{ 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
|
||||
{ 0x00000012, 108, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
|
||||
{ 0x0000003B, 112, DRAM_ID(6) }, // emc_txsr.
|
||||
{ 0x0000003B, 113, DRAM_ID(6) }, // emc_txsr_dll.
|
||||
{ 0x00000003, 119, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
|
||||
{ 0x00120015, 205, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x00160012, 206, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
||||
{ 0x00120015, 211, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00160012, 212, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
||||
{ 0x002F0032, 213, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00310032, 214, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00360034, 215, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0033002F, 216, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
||||
{ 0x00000006, 217, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x002F0032, 219, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00310032, 220, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00360034, 221, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0033002F, 222, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
||||
{ 0x00000006, 223, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00150015, 233, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x00120012, 235, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
|
||||
{ 0x00160016, 236, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
|
||||
{ 0x00000015, 237, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x00000012, 295, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
|
||||
{ 0x00000012, 296, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
|
||||
{ 0x00000007, 370, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
|
||||
{ 0x72A30504, 373, DRAM_ID(6) }, // mc_emem_arb_misc0.
|
||||
#endif
|
||||
// Samsung 8GB density config.
|
||||
{ 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
|
||||
{ 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
|
||||
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
|
||||
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
|
||||
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
|
||||
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
|
||||
{ 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
|
||||
};
|
||||
#undef DCFG_OFFSET_OF
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static const u8 _dram_cfg_lz[1262] = {
|
||||
0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
|
||||
0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,
|
||||
0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,
|
||||
0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,
|
||||
0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,
|
||||
0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,
|
||||
0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,
|
||||
0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,
|
||||
0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,
|
||||
0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,
|
||||
0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,
|
||||
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,
|
||||
0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,
|
||||
0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,
|
||||
0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,
|
||||
0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,
|
||||
0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,
|
||||
0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,
|
||||
0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,
|
||||
0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,
|
||||
0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,
|
||||
0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,
|
||||
0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,
|
||||
0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,
|
||||
0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,
|
||||
0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
|
||||
0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,
|
||||
0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
|
||||
0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
|
||||
0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,
|
||||
0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,
|
||||
0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,
|
||||
0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,
|
||||
0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,
|
||||
0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,
|
||||
0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,
|
||||
0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,
|
||||
0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,
|
||||
0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,
|
||||
0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,
|
||||
0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,
|
||||
0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,
|
||||
0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,
|
||||
0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,
|
||||
0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,
|
||||
0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,
|
||||
0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,
|
||||
0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,
|
||||
0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,
|
||||
0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,
|
||||
0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,
|
||||
0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,
|
||||
0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,
|
||||
0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,
|
||||
0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,
|
||||
0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,
|
||||
0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,
|
||||
0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,
|
||||
0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,
|
||||
0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,
|
||||
0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,
|
||||
0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,
|
||||
0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,
|
||||
0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,
|
||||
0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,
|
||||
0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,
|
||||
0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,
|
||||
0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,
|
||||
0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,
|
||||
0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,
|
||||
0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,
|
||||
0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,
|
||||
0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,
|
||||
0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,
|
||||
0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,
|
||||
0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,
|
||||
0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,
|
||||
0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,
|
||||
0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,
|
||||
0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,
|
||||
0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,
|
||||
0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,
|
||||
0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,
|
||||
0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,
|
||||
0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,
|
||||
0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,
|
||||
0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x17, 0x0D, 0x16,
|
||||
0x17, 0x0E, 0x82, 0x3C, 0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24,
|
||||
0x17, 0x5C, 0x8E, 0x68, 0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01,
|
||||
0x8E, 0x68, 0x02, 0x17, 0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78,
|
||||
0x17, 0x85, 0x28, 0x8E, 0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81,
|
||||
0x24, 0x8E, 0x68, 0x17, 0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04,
|
||||
0x30, 0x17, 0x85, 0x3C, 0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17,
|
||||
0x88, 0x74, 0x8E, 0x68, 0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04,
|
||||
0x04, 0x17, 0x12, 0x8E, 0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17,
|
||||
0x83, 0x04, 0x9D, 0x50, 0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B,
|
||||
0x49, 0x17, 0x0B, 0x18, 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00,
|
||||
0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17,
|
||||
0x18, 0x18, 0x17, 0x20, 0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06,
|
||||
0x5E, 0x16, 0x00, 0x15, 0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F,
|
||||
0xBB, 0x20, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38,
|
||||
0x3B, 0x17, 0x04, 0x04, 0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53,
|
||||
0xAC, 0x38, 0x07, 0x17, 0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10,
|
||||
0x8E, 0x68
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -16,8 +16,6 @@
|
|||
|
||||
#define DRAM_CFG_T210B01_SIZE 2104
|
||||
|
||||
#define DRAM_ID2(x) BIT((x) - 7)
|
||||
|
||||
static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
||||
/* Specifies the type of memory device */
|
||||
.memory_type = MEMORY_TYPE_LPDDR4,
|
||||
|
@ -109,7 +107,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.emc_pmacro_ca_tx_drive = 0x3F3F3F3F,
|
||||
.emc_pmacro_cmd_tx_drive = 0x00001220,
|
||||
.emc_pmacro_auto_cal_common = 0x00000804,
|
||||
.emc_pmacro_zcrtl = 0x505050,
|
||||
.emc_pmacro_zcrtl = 0x00505050,
|
||||
|
||||
/* Specifies the time for the calibration to stabilize (in microseconds) */
|
||||
.emc_auto_cal_wait = 0x000001A1,
|
||||
|
@ -122,7 +120,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
.emc_adr_cfg = 0x00000000, // 1 populated DRAM Device.
|
||||
.emc_adr_cfg = 0x00000000, // 1 Rank.
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
|
@ -273,7 +271,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.emc_cfg_dig_dll = 0x002C00A0,
|
||||
.emc_cfg_dig_dll_1 = 0x000F3701,
|
||||
.emc_cfg_dig_dll_period = 0x00008000,
|
||||
.emc_dev_select = 0x00000002, // Dev0 only.
|
||||
.emc_dev_select = 0x00000002, // Rank 0 only.
|
||||
.emc_sel_dpd_ctrl = 0x0004000C,
|
||||
|
||||
/* Pads trimmer delays */
|
||||
|
@ -543,9 +541,9 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.emc_pmacro_cmd_ctrl2 = 0x00000000,
|
||||
|
||||
/* DRAM size information */
|
||||
.mc_emem_adr_cfg = 0x00000000, // 1 populated DRAM Device.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00080302, // Density 1024MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00080302, // Density 1024MB.
|
||||
.mc_emem_adr_cfg = 0x00000000, // 1 Rank.
|
||||
.mc_emem_adr_cfg_dev0 = 0x00080302, // Chip 0 Density 1024MB.
|
||||
.mc_emem_adr_cfg_dev1 = 0x00080302, // Chip 1 Density 1024MB.
|
||||
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
|
||||
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
|
||||
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
|
||||
|
@ -554,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density.
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||
|
||||
/* MC arbitration configuration */
|
||||
.mc_emem_arb_cfg = 0x08000001,
|
||||
|
@ -596,13 +594,19 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
||||
.mc_video_protect_vpr_override1 = 0x06001ED3, // Add SE2, SE2B.
|
||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343.
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B and TSECB, TSEC1, TSECB1.
|
||||
.mc_video_protect_vpr_override1 = 0x0600FED3, // Default: 0x06001ED3.
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
|
||||
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
|
||||
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
|
||||
.mc_video_protect_write_access = 0x00000000,
|
||||
.mc_sec_carveout_protect_write_access = 0x00000000,
|
||||
|
||||
|
@ -703,300 +707,106 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.bct_na = 0x00000000,
|
||||
};
|
||||
|
||||
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
|
||||
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_PUPD_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_DSR (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_QUSE (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
|
||||
|
||||
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
|
||||
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
|
||||
|
||||
// Samsung LPDDR4X 4GB X1X2 for prototype Iowa.
|
||||
{ 0x000E0022, 0x3AC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x001B0010, 0x3B0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
||||
{ 0x000E0022, 0x3C4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x001B0010, 0x3C8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
||||
{ 0x00490043, 0x3CC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00420045, 0x3D0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00490047, 0x3D4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x00460047, 0x3D8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
||||
{ 0x00000016, 0x3DC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00100000, 0x3E0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
|
||||
{ 0x00490043, 0x3E4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00420045, 0x3E8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00490047, 0x3EC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x00460047, 0x3F0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
||||
{ 0x00000016, 0x3F4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00100000, 0x3F8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
|
||||
{ 0x00220022, 0x41C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000E000E, 0x420 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00100010, 0x424 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_2.
|
||||
{ 0x001B001B, 0x428 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_3.
|
||||
{ 0x00000022, 0x42C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
|
||||
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
|
||||
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_0) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_1) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_2) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_3) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_0) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_1) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
|
||||
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
|
||||
|
||||
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ for SDEV Iowa and Hoag.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00000006, 0x1CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput_duration.
|
||||
{ 0x08010004, 0x2B8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_dev_select. Both devices.
|
||||
{ 0x35353535, 0x350 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x35353535, 0x354 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x00100010, 0x3FC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00100010, 0x400 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00100010, 0x404 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00100010, 0x408 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00100010, 0x40C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00100010, 0x410 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00100010, 0x414 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00100010, 0x418 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
{ 0x0051004F, 0x450 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00002000, 0x64C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000002, 0x680 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override1.
|
||||
/*! Shared patched between DRAM Codes. */
|
||||
{ 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
|
||||
{ 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_vref_sel0) },
|
||||
|
||||
// Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT for Iowa and Hoag.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_dyn_self_ref_control.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override1.
|
||||
// Moved to default config.
|
||||
// { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
|
||||
// { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
|
||||
|
||||
// Samsung LPDDR4X 4GB Die-Y for Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(16) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(16) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(16) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(16) }, // emc_dyn_self_ref_control.
|
||||
{ 0x32323232, 0x350 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x32323232, 0x354 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x000F0018, 0x3AC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00780078, 0x3FC / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00780078, 0x400 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00780078, 0x404 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00780078, 0x408 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00780078, 0x40C / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00780078, 0x410 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00780078, 0x414 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00780078, 0x418 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
{ 0x00180018, 0x41C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override1.
|
||||
{ 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
|
||||
{ 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
|
||||
|
||||
// Samsung LPDDR4X 4GB 10nm-class (1y) Die-X for Iowa, Hoag and SDS.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000006, 0x1CC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput_duration.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_dyn_self_ref_control.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override1.
|
||||
{ 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
|
||||
{ 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
|
||||
{ 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
|
||||
{ 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
|
||||
|
||||
// Samsung LPDDR4X 8GB 10nm-class (1y) Die-X for SDEV Iowa and SDS.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00000006, 0x1CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput_duration.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_tfaw.
|
||||
{ 0x08010004, 0x2B8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_dev_select. Both devices.
|
||||
{ 0x0051004F, 0x450 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00002000, 0x64C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_faw.
|
||||
{ 0x00000002, 0x680 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override1.
|
||||
{ 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
|
||||
{ 0x00000001, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(mc_emem_arb_timing_faw) },
|
||||
|
||||
// Samsung LPDDR4X 4GB 10nm-class (1y) Die-Y for Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(20) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(20) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_ID2(20) }, // emc_tfaw.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(20) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(20) }, // emc_dyn_self_ref_control.
|
||||
{ 0x000F0018, 0x3AC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00180018, 0x41C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_ID2(20) }, // mc_emem_arb_timing_faw.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override1.
|
||||
// Moved to default config.
|
||||
// { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
|
||||
// { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
|
||||
|
||||
// Samsung LPDDR4X 8GB 10nm-class (1y) Die-Y for SDEV Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(21) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(21) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, DRAM_ID2(21) }, // emc_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_ID2(21) }, // emc_tfaw.
|
||||
{ 0x08010004, 0x2B8 / 4, DRAM_ID2(21) }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, DRAM_ID2(21) }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, DRAM_ID2(21) }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, DRAM_ID2(21) }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, DRAM_ID2(21) }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(21) }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(21) }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(21) }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, DRAM_ID2(21) }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, DRAM_ID2(21) }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, DRAM_ID2(21) }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, DRAM_ID2(21) }, // emc_dev_select. Both devices.
|
||||
{ 0x32323232, 0x350 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x32323232, 0x354 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x000F0018, 0x3AC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00180018, 0x41C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x0051004F, 0x450 / 4, DRAM_ID2(21) }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, DRAM_ID2(21) }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, DRAM_ID2(21) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
|
||||
{ 0x00002000, 0x64C / 4, DRAM_ID2(21) }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_faw.
|
||||
{ 0x00000002, 0x680 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, DRAM_ID2(21) }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override1.
|
||||
|
||||
// Samsung LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown SDS.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(22) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(22) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_ID2(22) }, // emc_tfaw.
|
||||
{ 0x1C041B06, 0x26C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_0.
|
||||
{ 0x02050307, 0x270 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_1.
|
||||
{ 0x03252500, 0x274 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_2.
|
||||
{ 0x081D1E00, 0x278 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_0.
|
||||
{ 0x090C0A0D, 0x27C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_1.
|
||||
{ 0x0526260B, 0x280 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_2.
|
||||
{ 0x05030402, 0x284 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_0.
|
||||
{ 0x1B1C0600, 0x288 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_1.
|
||||
{ 0x07252507, 0x28C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_2.
|
||||
{ 0x0C1D0B0A, 0x290 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_0.
|
||||
{ 0x0800090D, 0x294 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_1.
|
||||
{ 0x0926261E, 0x298 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_2.
|
||||
{ 0x2A080624, 0x29C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_byte.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(22) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(22) }, // emc_dyn_self_ref_control.
|
||||
{ 0x00140010, 0x3AC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x0013000B, 0x3B0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
||||
{ 0x00140010, 0x3C4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x0013000B, 0x3C8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
||||
{ 0x00450047, 0x3CC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x004D004F, 0x3D0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00460046, 0x3D4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x00480048, 0x3D8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
||||
{ 0x000C0008, 0x3DC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x000B000C, 0x3E0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
|
||||
{ 0x00450047, 0x3E4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x004D004F, 0x3E8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00460046, 0x3EC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x00480048, 0x3F0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
||||
{ 0x000C0008, 0x3F4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x000B000C, 0x3F8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
|
||||
{ 0x00100010, 0x41C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x00140014, 0x420 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00130013, 0x428 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_3.
|
||||
{ 0x00000010, 0x42C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x40280100, 0x4B4 / 4, DRAM_ID2(22) }, // pmc_ddr_cfg.
|
||||
{ 0x4F9F9FFF, 0x4B8 / 4, DRAM_ID2(22) }, // pmc_io_dpd3_req.
|
||||
{ 0x64032157, 0x4D8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte0.
|
||||
{ 0x51320467, 0x4DC / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte1.
|
||||
{ 0x04735621, 0x4E0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte2.
|
||||
{ 0x47356012, 0x4E4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte3.
|
||||
{ 0x12045673, 0x4E8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte0.
|
||||
{ 0x43657210, 0x4EC / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte1.
|
||||
{ 0x65402137, 0x4F0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte2.
|
||||
{ 0x57302164, 0x4F4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte3.
|
||||
{ 0x4F9F9FFF, 0x534 / 4, DRAM_ID2(22) }, // emc_pmc_scratch1.
|
||||
{ 0x4033CF1F, 0x53C / 4, DRAM_ID2(22) }, // emc_pmc_scratch3.
|
||||
{ 0x10000000, 0x590 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd3.
|
||||
{ 0x00030108, 0x594 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x01400050, 0x598 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x29081081, 0x5A0 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping0.
|
||||
{ 0x54A59332, 0x5A4 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping1.
|
||||
{ 0x87766B4A, 0x5A8 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping2.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_ID2(22) }, // mc_emem_arb_timing_faw.
|
||||
{ 0xE4FACB43, 0x6D4 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override. + TSEC, NVENC.
|
||||
{ 0x0600FED3, 0x6D8 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override1.
|
||||
{ 0x0000009C, 0x814 / 4, DRAM_ID2(22) }, // swizzle_rank_byte_encode.
|
||||
|
||||
// Micron LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown Iowa/Hoag/SDS.
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000006, 0x1CC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput_duration.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_tfaw.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_dyn_self_ref_control.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_emem_arb_timing_faw.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override1.
|
||||
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
|
||||
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
|
||||
{ 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
|
||||
{ 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
|
||||
{ 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
|
||||
{ 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
|
||||
{ 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
|
||||
{ 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
|
||||
{ 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
|
||||
{ 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
|
||||
{ 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
|
||||
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
|
||||
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
|
||||
{ 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
|
||||
{ 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
|
||||
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
|
||||
{ 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
|
||||
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
|
||||
{ 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
|
||||
{ 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
|
||||
{ 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
|
||||
};
|
||||
#undef DCFG_OFFSET_OF
|
||||
|
|
1538
bdk/mem/sdram_lp0.c
1538
bdk/mem/sdram_lp0.c
File diff suppressed because it is too large
Load diff
|
@ -1,964 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure.
|
||||
*
|
||||
* Note that PLLM is used by EMC. The field names are in camel case to ease
|
||||
* directly converting BCT config files (*.cfg) into C structure.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA210_SDRAM_PARAM_H__
|
||||
#define __TEGRA210_SDRAM_PARAM_H__
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
enum
|
||||
{
|
||||
/* Specifies the memory type to be undefined */
|
||||
NvBootMemoryType_None = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR SDRAM */
|
||||
NvBootMemoryType_Ddr = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR SDRAM */
|
||||
NvBootMemoryType_LpDdr = 0,
|
||||
|
||||
/* Specifies the memory type to be DDR2 SDRAM */
|
||||
NvBootMemoryType_Ddr2 = 0,
|
||||
|
||||
/* Specifies the memory type to be LPDDR2 SDRAM */
|
||||
NvBootMemoryType_LpDdr2,
|
||||
|
||||
/* Specifies the memory type to be DDR3 SDRAM */
|
||||
NvBootMemoryType_Ddr3,
|
||||
|
||||
/* Specifies the memory type to be LPDDR4 SDRAM */
|
||||
NvBootMemoryType_LpDdr4,
|
||||
|
||||
NvBootMemoryType_Num,
|
||||
|
||||
/* Specifies an entry in the ram_code table that's not in use */
|
||||
NvBootMemoryType_Unused = 0X7FFFFFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the SDRAM parameter structure
|
||||
*/
|
||||
struct sdram_params_t210
|
||||
{
|
||||
|
||||
/* Specifies the type of memory device */
|
||||
u32 MemoryType;
|
||||
|
||||
/* MC/EMC clock source configuration */
|
||||
|
||||
/* Specifies the M value for PllM */
|
||||
u32 PllMInputDivider;
|
||||
/* Specifies the N value for PllM */
|
||||
u32 PllMFeedbackDivider;
|
||||
/* Specifies the time to wait for PLLM to lock (in microseconds) */
|
||||
u32 PllMStableTime;
|
||||
/* Specifies misc. control bits */
|
||||
u32 PllMSetupControl;
|
||||
/* Specifies the P value for PLLM */
|
||||
u32 PllMPostDivider;
|
||||
/* Specifies value for Charge Pump Gain Control */
|
||||
u32 PllMKCP;
|
||||
/* Specifies VCO gain */
|
||||
u32 PllMKVCO;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare0;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare1;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare2;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare3;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare4;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare5;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare6;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare7;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare8;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare9;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare10;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare11;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare12;
|
||||
/* Spare BCT param */
|
||||
u32 EmcBctSpare13;
|
||||
|
||||
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
|
||||
u32 EmcClockSource;
|
||||
u32 EmcClockSourceDll;
|
||||
|
||||
/* Defines possible override for PLLLM_MISC2 */
|
||||
u32 ClkRstControllerPllmMisc2Override;
|
||||
/* enables override for PLLLM_MISC2 */
|
||||
u32 ClkRstControllerPllmMisc2OverrideEnable;
|
||||
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
|
||||
u32 ClearClk2Mc1;
|
||||
|
||||
/* Auto-calibration of EMC pads */
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
|
||||
u32 EmcAutoCalInterval;
|
||||
/*
|
||||
* Specifies the value for EMC_AUTO_CAL_CONFIG
|
||||
* Note: Trigger bits are set by the SDRAM code.
|
||||
*/
|
||||
u32 EmcAutoCalConfig;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
|
||||
u32 EmcAutoCalConfig2;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
|
||||
u32 EmcAutoCalConfig3;
|
||||
|
||||
/* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
|
||||
u32 EmcAutoCalConfig4;
|
||||
u32 EmcAutoCalConfig5;
|
||||
u32 EmcAutoCalConfig6;
|
||||
u32 EmcAutoCalConfig7;
|
||||
u32 EmcAutoCalConfig8;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
|
||||
u32 EmcAutoCalVrefSel0;
|
||||
u32 EmcAutoCalVrefSel1;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
|
||||
u32 EmcAutoCalChannel;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
|
||||
u32 EmcPmacroAutocalCfg0;
|
||||
u32 EmcPmacroAutocalCfg1;
|
||||
u32 EmcPmacroAutocalCfg2;
|
||||
u32 EmcPmacroRxTerm;
|
||||
u32 EmcPmacroDqTxDrv;
|
||||
u32 EmcPmacroCaTxDrv;
|
||||
u32 EmcPmacroCmdTxDrv;
|
||||
u32 EmcPmacroAutocalCfgCommon;
|
||||
u32 EmcPmacroZctrl;
|
||||
|
||||
/*
|
||||
* Specifies the time for the calibration
|
||||
* to stabilize (in microseconds)
|
||||
*/
|
||||
u32 EmcAutoCalWait;
|
||||
|
||||
u32 EmcXm2CompPadCtrl;
|
||||
u32 EmcXm2CompPadCtrl2;
|
||||
u32 EmcXm2CompPadCtrl3;
|
||||
|
||||
/*
|
||||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
u32 EmcAdrCfg;
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
* CKE (in microseconds)
|
||||
*/
|
||||
u32 EmcPinProgramWait;
|
||||
/* Specifies the extra delay before/after pin RESET/CKE command */
|
||||
u32 EmcPinExtraWait;
|
||||
|
||||
u32 EmcPinGpioEn;
|
||||
u32 EmcPinGpio;
|
||||
|
||||
/*
|
||||
* Specifies the extra delay after the first writing
|
||||
* of EMC_TIMING_CONTROL
|
||||
*/
|
||||
u32 EmcTimingControlWait;
|
||||
|
||||
/* Timing parameters required for the SDRAM */
|
||||
|
||||
/* Specifies the value for EMC_RC */
|
||||
u32 EmcRc;
|
||||
/* Specifies the value for EMC_RFC */
|
||||
u32 EmcRfc;
|
||||
/* Specifies the value for EMC_RFC_PB */
|
||||
u32 EmcRfcPb;
|
||||
/* Specifies the value for EMC_RFC_CTRL2 */
|
||||
u32 EmcRefctrl2;
|
||||
/* Specifies the value for EMC_RFC_SLR */
|
||||
u32 EmcRfcSlr;
|
||||
/* Specifies the value for EMC_RAS */
|
||||
u32 EmcRas;
|
||||
/* Specifies the value for EMC_RP */
|
||||
u32 EmcRp;
|
||||
/* Specifies the value for EMC_R2R */
|
||||
u32 EmcR2r;
|
||||
/* Specifies the value for EMC_W2W */
|
||||
u32 EmcW2w;
|
||||
/* Specifies the value for EMC_R2W */
|
||||
u32 EmcR2w;
|
||||
/* Specifies the value for EMC_W2R */
|
||||
u32 EmcW2r;
|
||||
/* Specifies the value for EMC_R2P */
|
||||
u32 EmcR2p;
|
||||
/* Specifies the value for EMC_W2P */
|
||||
u32 EmcW2p;
|
||||
|
||||
u32 EmcTppd;
|
||||
u32 EmcCcdmw;
|
||||
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
u32 EmcRdRcd;
|
||||
/* Specifies the value for EMC_WR_RCD */
|
||||
u32 EmcWrRcd;
|
||||
/* Specifies the value for EMC_RRD */
|
||||
u32 EmcRrd;
|
||||
/* Specifies the value for EMC_REXT */
|
||||
u32 EmcRext;
|
||||
/* Specifies the value for EMC_WEXT */
|
||||
u32 EmcWext;
|
||||
/* Specifies the value for EMC_WDV */
|
||||
u32 EmcWdv;
|
||||
|
||||
u32 EmcWdvChk;
|
||||
u32 EmcWsv;
|
||||
u32 EmcWev;
|
||||
|
||||
/* Specifies the value for EMC_WDV_MASK */
|
||||
u32 EmcWdvMask;
|
||||
|
||||
u32 EmcWsDuration;
|
||||
u32 EmcWeDuration;
|
||||
|
||||
/* Specifies the value for EMC_QUSE */
|
||||
u32 EmcQUse;
|
||||
/* Specifies the value for EMC_QUSE_WIDTH */
|
||||
u32 EmcQuseWidth;
|
||||
/* Specifies the value for EMC_IBDLY */
|
||||
u32 EmcIbdly;
|
||||
/* Specifies the value for EMC_OBDLY */
|
||||
u32 EmcObdly;
|
||||
/* Specifies the value for EMC_EINPUT */
|
||||
u32 EmcEInput;
|
||||
/* Specifies the value for EMC_EINPUT_DURATION */
|
||||
u32 EmcEInputDuration;
|
||||
/* Specifies the value for EMC_PUTERM_EXTRA */
|
||||
u32 EmcPutermExtra;
|
||||
/* Specifies the value for EMC_PUTERM_WIDTH */
|
||||
u32 EmcPutermWidth;
|
||||
/* Specifies the value for EMC_PUTERM_ADJ */
|
||||
////u32 EmcPutermAdj;
|
||||
|
||||
/* Specifies the value for EMC_QRST */
|
||||
u32 EmcQRst;
|
||||
/* Specifies the value for EMC_QSAFE */
|
||||
u32 EmcQSafe;
|
||||
/* Specifies the value for EMC_RDV */
|
||||
u32 EmcRdv;
|
||||
/* Specifies the value for EMC_RDV_MASK */
|
||||
u32 EmcRdvMask;
|
||||
/* Specifies the value for EMC_RDV_EARLY */
|
||||
u32 EmcRdvEarly;
|
||||
/* Specifies the value for EMC_RDV_EARLY_MASK */
|
||||
u32 EmcRdvEarlyMask;
|
||||
/* Specifies the value for EMC_QPOP */
|
||||
u32 EmcQpop;
|
||||
|
||||
/* Specifies the value for EMC_REFRESH */
|
||||
u32 EmcRefresh;
|
||||
/* Specifies the value for EMC_BURST_REFRESH_NUM */
|
||||
u32 EmcBurstRefreshNum;
|
||||
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
|
||||
u32 EmcPreRefreshReqCnt;
|
||||
/* Specifies the value for EMC_PDEX2WR */
|
||||
u32 EmcPdEx2Wr;
|
||||
/* Specifies the value for EMC_PDEX2RD */
|
||||
u32 EmcPdEx2Rd;
|
||||
/* Specifies the value for EMC_PCHG2PDEN */
|
||||
u32 EmcPChg2Pden;
|
||||
/* Specifies the value for EMC_ACT2PDEN */
|
||||
u32 EmcAct2Pden;
|
||||
/* Specifies the value for EMC_AR2PDEN */
|
||||
u32 EmcAr2Pden;
|
||||
/* Specifies the value for EMC_RW2PDEN */
|
||||
u32 EmcRw2Pden;
|
||||
/* Specifies the value for EMC_CKE2PDEN */
|
||||
u32 EmcCke2Pden;
|
||||
/* Specifies the value for EMC_PDEX2CKE */
|
||||
u32 EmcPdex2Cke;
|
||||
/* Specifies the value for EMC_PDEX2MRR */
|
||||
u32 EmcPdex2Mrr;
|
||||
/* Specifies the value for EMC_TXSR */
|
||||
u32 EmcTxsr;
|
||||
/* Specifies the value for EMC_TXSRDLL */
|
||||
u32 EmcTxsrDll;
|
||||
/* Specifies the value for EMC_TCKE */
|
||||
u32 EmcTcke;
|
||||
/* Specifies the value for EMC_TCKESR */
|
||||
u32 EmcTckesr;
|
||||
/* Specifies the value for EMC_TPD */
|
||||
u32 EmcTpd;
|
||||
/* Specifies the value for EMC_TFAW */
|
||||
u32 EmcTfaw;
|
||||
/* Specifies the value for EMC_TRPAB */
|
||||
u32 EmcTrpab;
|
||||
/* Specifies the value for EMC_TCLKSTABLE */
|
||||
u32 EmcTClkStable;
|
||||
/* Specifies the value for EMC_TCLKSTOP */
|
||||
u32 EmcTClkStop;
|
||||
/* Specifies the value for EMC_TREFBW */
|
||||
u32 EmcTRefBw;
|
||||
|
||||
/* FBIO configuration values */
|
||||
|
||||
/* Specifies the value for EMC_FBIO_CFG5 */
|
||||
u32 EmcFbioCfg5;
|
||||
/* Specifies the value for EMC_FBIO_CFG7 */
|
||||
u32 EmcFbioCfg7;
|
||||
/* Specifies the value for EMC_FBIO_CFG8 */
|
||||
u32 EmcFbioCfg8;
|
||||
|
||||
/* Command mapping for CMD brick 0 */
|
||||
u32 EmcCmdMappingCmd0_0;
|
||||
u32 EmcCmdMappingCmd0_1;
|
||||
u32 EmcCmdMappingCmd0_2;
|
||||
u32 EmcCmdMappingCmd1_0;
|
||||
u32 EmcCmdMappingCmd1_1;
|
||||
u32 EmcCmdMappingCmd1_2;
|
||||
u32 EmcCmdMappingCmd2_0;
|
||||
u32 EmcCmdMappingCmd2_1;
|
||||
u32 EmcCmdMappingCmd2_2;
|
||||
u32 EmcCmdMappingCmd3_0;
|
||||
u32 EmcCmdMappingCmd3_1;
|
||||
u32 EmcCmdMappingCmd3_2;
|
||||
u32 EmcCmdMappingByte;
|
||||
|
||||
/* Specifies the value for EMC_FBIO_SPARE */
|
||||
u32 EmcFbioSpare;
|
||||
|
||||
/* Specifies the value for EMC_CFG_RSV */
|
||||
u32 EmcCfgRsv;
|
||||
|
||||
/* MRS command values */
|
||||
|
||||
/* Specifies the value for EMC_MRS */
|
||||
u32 EmcMrs;
|
||||
/* Specifies the MP0 command to initialize mode registers */
|
||||
u32 EmcEmrs;
|
||||
/* Specifies the MP2 command to initialize mode registers */
|
||||
u32 EmcEmrs2;
|
||||
/* Specifies the MP3 command to initialize mode registers */
|
||||
u32 EmcEmrs3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
|
||||
u32 EmcMrw1;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
|
||||
u32 EmcMrw2;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
|
||||
u32 EmcMrw3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
u32 EmcMrw4;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
|
||||
u32 EmcMrw6;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
u32 EmcMrw8;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
|
||||
u32 EmcMrw9;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
|
||||
u32 EmcMrw10;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
|
||||
u32 EmcMrw12;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
|
||||
u32 EmcMrw13;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
|
||||
u32 EmcMrw14;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at cold boot
|
||||
*/
|
||||
u32 EmcMrwExtra;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at warm boot
|
||||
*/
|
||||
u32 EmcWarmBootMrwExtra;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* warm boot
|
||||
*/
|
||||
u32 EmcWarmBootExtraModeRegWriteEnable;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* cold boot
|
||||
*/
|
||||
u32 EmcExtraModeRegWriteEnable;
|
||||
|
||||
/* Specifies the EMC_MRW reset command value */
|
||||
u32 EmcMrwResetCommand;
|
||||
/* Specifies the EMC Reset wait time (in microseconds) */
|
||||
u32 EmcMrwResetNInitWait;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT */
|
||||
u32 EmcMrsWaitCnt;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
|
||||
u32 EmcMrsWaitCnt2;
|
||||
|
||||
/* EMC miscellaneous configurations */
|
||||
|
||||
/* Specifies the value for EMC_CFG */
|
||||
u32 EmcCfg;
|
||||
/* Specifies the value for EMC_CFG_2 */
|
||||
u32 EmcCfg2;
|
||||
/* Specifies the pipe bypass controls */
|
||||
u32 EmcCfgPipe;
|
||||
u32 EmcCfgPipeClk;
|
||||
u32 EmcFdpdCtrlCmdNoRamp;
|
||||
u32 EmcCfgUpdate;
|
||||
|
||||
/* Specifies the value for EMC_DBG */
|
||||
u32 EmcDbg;
|
||||
u32 EmcDbgWriteMux;
|
||||
|
||||
/* Specifies the value for EMC_CMDQ */
|
||||
u32 EmcCmdQ;
|
||||
/* Specifies the value for EMC_MC2EMCQ */
|
||||
u32 EmcMc2EmcQ;
|
||||
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
|
||||
u32 EmcDynSelfRefControl;
|
||||
|
||||
/* Specifies the value for MEM_INIT_DONE */
|
||||
u32 AhbArbitrationXbarCtrlMemInitDone;
|
||||
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL */
|
||||
u32 EmcCfgDigDll;
|
||||
u32 EmcCfgDigDll_1;
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
|
||||
u32 EmcCfgDigDllPeriod;
|
||||
/* Specifies the value of *DEV_SELECTN of various EMC registers */
|
||||
u32 EmcDevSelect;
|
||||
|
||||
/* Specifies the value for EMC_SEL_DPD_CTRL */
|
||||
u32 EmcSelDpdCtrl;
|
||||
|
||||
/* Pads trimmer delays */
|
||||
u32 EmcFdpdCtrlDq;
|
||||
u32 EmcFdpdCtrlCmd;
|
||||
u32 EmcPmacroIbVrefDq_0;
|
||||
u32 EmcPmacroIbVrefDq_1;
|
||||
u32 EmcPmacroIbVrefDqs_0;
|
||||
u32 EmcPmacroIbVrefDqs_1;
|
||||
u32 EmcPmacroIbRxrt;
|
||||
u32 EmcCfgPipe1;
|
||||
u32 EmcCfgPipe2;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
|
||||
u32 EmcPmacroQuseDdllRank0_0;
|
||||
u32 EmcPmacroQuseDdllRank0_1;
|
||||
u32 EmcPmacroQuseDdllRank0_2;
|
||||
u32 EmcPmacroQuseDdllRank0_3;
|
||||
u32 EmcPmacroQuseDdllRank0_4;
|
||||
u32 EmcPmacroQuseDdllRank0_5;
|
||||
u32 EmcPmacroQuseDdllRank1_0;
|
||||
u32 EmcPmacroQuseDdllRank1_1;
|
||||
u32 EmcPmacroQuseDdllRank1_2;
|
||||
u32 EmcPmacroQuseDdllRank1_3;
|
||||
u32 EmcPmacroQuseDdllRank1_4;
|
||||
u32 EmcPmacroQuseDdllRank1_5;
|
||||
|
||||
u32 EmcPmacroObDdllLongDqRank0_0;
|
||||
u32 EmcPmacroObDdllLongDqRank0_1;
|
||||
u32 EmcPmacroObDdllLongDqRank0_2;
|
||||
u32 EmcPmacroObDdllLongDqRank0_3;
|
||||
u32 EmcPmacroObDdllLongDqRank0_4;
|
||||
u32 EmcPmacroObDdllLongDqRank0_5;
|
||||
u32 EmcPmacroObDdllLongDqRank1_0;
|
||||
u32 EmcPmacroObDdllLongDqRank1_1;
|
||||
u32 EmcPmacroObDdllLongDqRank1_2;
|
||||
u32 EmcPmacroObDdllLongDqRank1_3;
|
||||
u32 EmcPmacroObDdllLongDqRank1_4;
|
||||
u32 EmcPmacroObDdllLongDqRank1_5;
|
||||
|
||||
u32 EmcPmacroObDdllLongDqsRank0_0;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_1;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_2;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_3;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_4;
|
||||
u32 EmcPmacroObDdllLongDqsRank0_5;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_0;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_1;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_2;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_3;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_4;
|
||||
u32 EmcPmacroObDdllLongDqsRank1_5;
|
||||
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_0;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_1;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_2;
|
||||
u32 EmcPmacroIbDdllLongDqsRank0_3;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_0;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_1;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_2;
|
||||
u32 EmcPmacroIbDdllLongDqsRank1_3;
|
||||
|
||||
u32 EmcPmacroDdllLongCmd_0;
|
||||
u32 EmcPmacroDdllLongCmd_1;
|
||||
u32 EmcPmacroDdllLongCmd_2;
|
||||
u32 EmcPmacroDdllLongCmd_3;
|
||||
u32 EmcPmacroDdllLongCmd_4;
|
||||
u32 EmcPmacroDdllShortCmd_0;
|
||||
u32 EmcPmacroDdllShortCmd_1;
|
||||
u32 EmcPmacroDdllShortCmd_2;
|
||||
|
||||
/*
|
||||
* Specifies the delay after asserting CKE pin during a WarmBoot0
|
||||
* sequence (in microseconds)
|
||||
*/
|
||||
u32 WarmBootWait;
|
||||
|
||||
/* Specifies the value for EMC_ODT_WRITE */
|
||||
u32 EmcOdtWrite;
|
||||
|
||||
/* Periodic ZQ calibration */
|
||||
|
||||
/*
|
||||
* Specifies the value for EMC_ZCAL_INTERVAL
|
||||
* Value 0 disables ZQ calibration
|
||||
*/
|
||||
u32 EmcZcalInterval;
|
||||
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
|
||||
u32 EmcZcalWaitCnt;
|
||||
/* Specifies the value for EMC_ZCAL_MRW_CMD */
|
||||
u32 EmcZcalMrwCmd;
|
||||
|
||||
/* DRAM initialization sequence flow control */
|
||||
|
||||
/* Specifies the MRS command value for resetting DLL */
|
||||
u32 EmcMrsResetDll;
|
||||
/* Specifies the command for ZQ initialization of device 0 */
|
||||
u32 EmcZcalInitDev0;
|
||||
/* Specifies the command for ZQ initialization of device 1 */
|
||||
u32 EmcZcalInitDev1;
|
||||
/*
|
||||
* Specifies the wait time after programming a ZQ initialization
|
||||
* command (in microseconds)
|
||||
*/
|
||||
u32 EmcZcalInitWait;
|
||||
/*
|
||||
* Specifies the enable for ZQ calibration at cold boot [bit 0]
|
||||
* and warm boot [bit 1]
|
||||
*/
|
||||
u32 EmcZcalWarmColdBootEnables;
|
||||
|
||||
/*
|
||||
* Specifies the MRW command to LPDDR2 for ZQ calibration
|
||||
* on warmboot
|
||||
*/
|
||||
/* Is issued to both devices separately */
|
||||
u32 EmcMrwLpddr2ZcalWarmBoot;
|
||||
/*
|
||||
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
|
||||
* Is issued to both devices separately
|
||||
*/
|
||||
u32 EmcZqCalDdr3WarmBoot;
|
||||
u32 EmcZqCalLpDdr4WarmBoot;
|
||||
/*
|
||||
* Specifies the wait time for ZQ calibration on warmboot
|
||||
* (in microseconds)
|
||||
*/
|
||||
u32 EmcZcalWarmBootWait;
|
||||
/*
|
||||
* Specifies the enable for DRAM Mode Register programming
|
||||
* at warm boot
|
||||
*/
|
||||
u32 EmcMrsWarmBootEnable;
|
||||
/*
|
||||
* Specifies the wait time after sending an MRS DLL reset command
|
||||
* in microseconds)
|
||||
*/
|
||||
u32 EmcMrsResetDllWait;
|
||||
/* Specifies the extra MRS command to initialize mode registers */
|
||||
u32 EmcMrsExtra;
|
||||
/* Specifies the extra MRS command at warm boot */
|
||||
u32 EmcWarmBootMrsExtra;
|
||||
/* Specifies the EMRS command to enable the DDR2 DLL */
|
||||
u32 EmcEmrsDdr2DllEnable;
|
||||
/* Specifies the MRS command to reset the DDR2 DLL */
|
||||
u32 EmcMrsDdr2DllReset;
|
||||
/* Specifies the EMRS command to set OCD calibration */
|
||||
u32 EmcEmrsDdr2OcdCalib;
|
||||
/*
|
||||
* Specifies the wait between initializing DDR and setting OCD
|
||||
* calibration (in microseconds)
|
||||
*/
|
||||
u32 EmcDdr2Wait;
|
||||
/* Specifies the value for EMC_CLKEN_OVERRIDE */
|
||||
u32 EmcClkenOverride;
|
||||
|
||||
/*
|
||||
* Specifies LOG2 of the extra refresh numbers after booting
|
||||
* Program 0 to disable
|
||||
*/
|
||||
u32 EmcExtraRefreshNum;
|
||||
/* Specifies the master override for all EMC clocks */
|
||||
u32 EmcClkenOverrideAllWarmBoot;
|
||||
/* Specifies the master override for all MC clocks */
|
||||
u32 McClkenOverrideAllWarmBoot;
|
||||
/* Specifies digital dll period, choosing between 4 to 64 ms */
|
||||
u32 EmcCfgDigDllPeriodWarmBoot;
|
||||
|
||||
/* Pad controls */
|
||||
|
||||
/* Specifies the value for PMC_VDDP_SEL */
|
||||
u32 PmcVddpSel;
|
||||
/* Specifies the wait time after programming PMC_VDDP_SEL */
|
||||
u32 PmcVddpSelWait;
|
||||
/* Specifies the value for PMC_DDR_PWR */
|
||||
u32 PmcDdrPwr;
|
||||
/* Specifies the value for PMC_DDR_CFG */
|
||||
u32 PmcDdrCfg;
|
||||
/* Specifies the value for PMC_IO_DPD3_REQ */
|
||||
u32 PmcIoDpd3Req;
|
||||
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
|
||||
u32 PmcIoDpd3ReqWait;
|
||||
u32 PmcIoDpd4ReqWait;
|
||||
|
||||
/* Specifies the value for PMC_REG_SHORT */
|
||||
u32 PmcRegShort;
|
||||
/* Specifies the value for PMC_NO_IOPOWER */
|
||||
u32 PmcNoIoPower;
|
||||
|
||||
u32 PmcDdrCntrlWait;
|
||||
u32 PmcDdrCntrl;
|
||||
|
||||
/* Specifies the value for EMC_ACPD_CONTROL */
|
||||
u32 EmcAcpdControl;
|
||||
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
|
||||
////u32 EmcSwizzleRank0ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
|
||||
u32 EmcSwizzleRank0Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
|
||||
u32 EmcSwizzleRank0Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
|
||||
u32 EmcSwizzleRank0Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
|
||||
u32 EmcSwizzleRank0Byte3;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
|
||||
////u32 EmcSwizzleRank1ByteCfg;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
|
||||
u32 EmcSwizzleRank1Byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
|
||||
u32 EmcSwizzleRank1Byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
|
||||
u32 EmcSwizzleRank1Byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
|
||||
u32 EmcSwizzleRank1Byte3;
|
||||
|
||||
/* Specifies the value for EMC_TXDSRVTTGEN */
|
||||
u32 EmcTxdsrvttgen;
|
||||
|
||||
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
|
||||
u32 EmcDataBrlshft0;
|
||||
u32 EmcDataBrlshft1;
|
||||
|
||||
u32 EmcDqsBrlshft0;
|
||||
u32 EmcDqsBrlshft1;
|
||||
|
||||
u32 EmcCmdBrlshft0;
|
||||
u32 EmcCmdBrlshft1;
|
||||
u32 EmcCmdBrlshft2;
|
||||
u32 EmcCmdBrlshft3;
|
||||
|
||||
u32 EmcQuseBrlshft0;
|
||||
u32 EmcQuseBrlshft1;
|
||||
u32 EmcQuseBrlshft2;
|
||||
u32 EmcQuseBrlshft3;
|
||||
|
||||
u32 EmcDllCfg0;
|
||||
u32 EmcDllCfg1;
|
||||
|
||||
u32 EmcPmcScratch1;
|
||||
u32 EmcPmcScratch2;
|
||||
u32 EmcPmcScratch3;
|
||||
|
||||
u32 EmcPmacroPadCfgCtrl;
|
||||
|
||||
u32 EmcPmacroVttgenCtrl0;
|
||||
u32 EmcPmacroVttgenCtrl1;
|
||||
u32 EmcPmacroVttgenCtrl2;
|
||||
|
||||
u32 EmcPmacroBrickCtrlRfu1;
|
||||
u32 EmcPmacroCmdBrickCtrlFdpd;
|
||||
u32 EmcPmacroBrickCtrlRfu2;
|
||||
u32 EmcPmacroDataBrickCtrlFdpd;
|
||||
u32 EmcPmacroBgBiasCtrl0;
|
||||
u32 EmcPmacroDataPadRxCtrl;
|
||||
u32 EmcPmacroCmdPadRxCtrl;
|
||||
u32 EmcPmacroDataRxTermMode;
|
||||
u32 EmcPmacroCmdRxTermMode;
|
||||
u32 EmcPmacroDataPadTxCtrl;
|
||||
u32 EmcPmacroCommonPadTxCtrl;
|
||||
u32 EmcPmacroCmdPadTxCtrl;
|
||||
u32 EmcCfg3;
|
||||
|
||||
u32 EmcPmacroTxPwrd0;
|
||||
u32 EmcPmacroTxPwrd1;
|
||||
u32 EmcPmacroTxPwrd2;
|
||||
u32 EmcPmacroTxPwrd3;
|
||||
u32 EmcPmacroTxPwrd4;
|
||||
u32 EmcPmacroTxPwrd5;
|
||||
|
||||
u32 EmcConfigSampleDelay;
|
||||
|
||||
u32 EmcPmacroBrickMapping0;
|
||||
u32 EmcPmacroBrickMapping1;
|
||||
u32 EmcPmacroBrickMapping2;
|
||||
|
||||
u32 EmcPmacroTxSelClkSrc0;
|
||||
u32 EmcPmacroTxSelClkSrc1;
|
||||
u32 EmcPmacroTxSelClkSrc2;
|
||||
u32 EmcPmacroTxSelClkSrc3;
|
||||
u32 EmcPmacroTxSelClkSrc4;
|
||||
u32 EmcPmacroTxSelClkSrc5;
|
||||
|
||||
u32 EmcPmacroDdllBypass;
|
||||
|
||||
u32 EmcPmacroDdllPwrd0;
|
||||
u32 EmcPmacroDdllPwrd1;
|
||||
u32 EmcPmacroDdllPwrd2;
|
||||
|
||||
u32 EmcPmacroCmdCtrl0;
|
||||
u32 EmcPmacroCmdCtrl1;
|
||||
u32 EmcPmacroCmdCtrl2;
|
||||
|
||||
/* DRAM size information */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG */
|
||||
u32 McEmemAdrCfg;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
|
||||
u32 McEmemAdrCfgDev0;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
|
||||
u32 McEmemAdrCfgDev1;
|
||||
u32 McEmemAdrCfgChannelMask;
|
||||
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
|
||||
u32 McEmemAdrCfgBankMask0;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
|
||||
u32 McEmemAdrCfgBankMask1;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
|
||||
u32 McEmemAdrCfgBankMask2;
|
||||
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
u32 McEmemCfg;
|
||||
|
||||
/* MC arbitration configuration */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_CFG */
|
||||
u32 McEmemArbCfg;
|
||||
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
|
||||
u32 McEmemArbOutstandingReq;
|
||||
|
||||
u32 McEmemArbRefpbHpCtrl;
|
||||
u32 McEmemArbRefpbBankCtrl;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
|
||||
u32 McEmemArbTimingRcd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
|
||||
u32 McEmemArbTimingRp;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
|
||||
u32 McEmemArbTimingRc;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
|
||||
u32 McEmemArbTimingRas;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
|
||||
u32 McEmemArbTimingFaw;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
|
||||
u32 McEmemArbTimingRrd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
|
||||
u32 McEmemArbTimingRap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
|
||||
u32 McEmemArbTimingWap2Pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
|
||||
u32 McEmemArbTimingR2R;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
|
||||
u32 McEmemArbTimingW2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
|
||||
u32 McEmemArbTimingR2W;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
|
||||
u32 McEmemArbTimingW2R;
|
||||
|
||||
u32 McEmemArbTimingRFCPB;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
|
||||
u32 McEmemArbDaTurns;
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
|
||||
u32 McEmemArbDaCovers;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC0 */
|
||||
u32 McEmemArbMisc0;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC1 */
|
||||
u32 McEmemArbMisc1;
|
||||
u32 McEmemArbMisc2;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
|
||||
u32 McEmemArbRing1Throttle;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
|
||||
u32 McEmemArbOverride;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
|
||||
u32 McEmemArbOverride1;
|
||||
/* Specifies the value for MC_EMEM_ARB_RSV */
|
||||
u32 McEmemArbRsv;
|
||||
|
||||
u32 McDaCfg0;
|
||||
u32 McEmemArbTimingCcdmw;
|
||||
|
||||
/* Specifies the value for MC_CLKEN_OVERRIDE */
|
||||
u32 McClkenOverride;
|
||||
|
||||
/* Specifies the value for MC_STAT_CONTROL */
|
||||
u32 McStatControl;
|
||||
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
|
||||
u32 McVideoProtectBom;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
|
||||
u32 McVideoProtectBomAdrHi;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
|
||||
u32 McVideoProtectSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
|
||||
u32 McVideoProtectVprOverride;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
|
||||
u32 McVideoProtectVprOverride1;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
|
||||
u32 McVideoProtectGpuOverride0;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
|
||||
u32 McVideoProtectGpuOverride1;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
|
||||
u32 McSecCarveoutBom;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
|
||||
u32 McSecCarveoutAdrHi;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
|
||||
u32 McSecCarveoutSizeMb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
|
||||
VIDEO_PROTECT_WRITEAccess */
|
||||
u32 McVideoProtectWriteAccess;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
|
||||
SEC_CARVEOUT_WRITEAccess */
|
||||
u32 McSecCarveoutProtectWriteAccess;
|
||||
|
||||
/* Write-Protect Regions (WPR) */
|
||||
u32 McGeneralizedCarveout1Bom;
|
||||
u32 McGeneralizedCarveout1BomHi;
|
||||
u32 McGeneralizedCarveout1Size128kb;
|
||||
u32 McGeneralizedCarveout1Access0;
|
||||
u32 McGeneralizedCarveout1Access1;
|
||||
u32 McGeneralizedCarveout1Access2;
|
||||
u32 McGeneralizedCarveout1Access3;
|
||||
u32 McGeneralizedCarveout1Access4;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout1ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout1Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout2Bom;
|
||||
u32 McGeneralizedCarveout2BomHi;
|
||||
u32 McGeneralizedCarveout2Size128kb;
|
||||
u32 McGeneralizedCarveout2Access0;
|
||||
u32 McGeneralizedCarveout2Access1;
|
||||
u32 McGeneralizedCarveout2Access2;
|
||||
u32 McGeneralizedCarveout2Access3;
|
||||
u32 McGeneralizedCarveout2Access4;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout2ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout2Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout3Bom;
|
||||
u32 McGeneralizedCarveout3BomHi;
|
||||
u32 McGeneralizedCarveout3Size128kb;
|
||||
u32 McGeneralizedCarveout3Access0;
|
||||
u32 McGeneralizedCarveout3Access1;
|
||||
u32 McGeneralizedCarveout3Access2;
|
||||
u32 McGeneralizedCarveout3Access3;
|
||||
u32 McGeneralizedCarveout3Access4;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout3ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout3Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout4Bom;
|
||||
u32 McGeneralizedCarveout4BomHi;
|
||||
u32 McGeneralizedCarveout4Size128kb;
|
||||
u32 McGeneralizedCarveout4Access0;
|
||||
u32 McGeneralizedCarveout4Access1;
|
||||
u32 McGeneralizedCarveout4Access2;
|
||||
u32 McGeneralizedCarveout4Access3;
|
||||
u32 McGeneralizedCarveout4Access4;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout4ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout4Cfg0;
|
||||
|
||||
u32 McGeneralizedCarveout5Bom;
|
||||
u32 McGeneralizedCarveout5BomHi;
|
||||
u32 McGeneralizedCarveout5Size128kb;
|
||||
u32 McGeneralizedCarveout5Access0;
|
||||
u32 McGeneralizedCarveout5Access1;
|
||||
u32 McGeneralizedCarveout5Access2;
|
||||
u32 McGeneralizedCarveout5Access3;
|
||||
u32 McGeneralizedCarveout5Access4;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess0;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess1;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess2;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess3;
|
||||
u32 McGeneralizedCarveout5ForceInternalAccess4;
|
||||
u32 McGeneralizedCarveout5Cfg0;
|
||||
|
||||
/* Specifies enable for CA training */
|
||||
u32 EmcCaTrainingEnable;
|
||||
|
||||
/* Set if bit 6 select is greater than bit 7 select; uses aremc.
|
||||
spec packet SWIZZLE_BIT6_GT_BIT7 */
|
||||
u32 SwizzleRankByteEncode;
|
||||
/* Specifies enable and offset for patched boot ROM write */
|
||||
u32 BootRomPatchControl;
|
||||
/* Specifies data for patched boot ROM write */
|
||||
u32 BootRomPatchData;
|
||||
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
|
||||
u32 McMtsCarveoutBom;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
|
||||
u32 McMtsCarveoutAdrHi;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
|
||||
u32 McMtsCarveoutSizeMb;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
|
||||
u32 McMtsCarveoutRegCtrl;
|
||||
|
||||
/* End */
|
||||
};
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */
|
|
@ -1,990 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA210B01_SDRAM_PARAM_H__
|
||||
#define __TEGRA210B01_SDRAM_PARAM_H__
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
struct sdram_params_t210b01
|
||||
{
|
||||
/* Specifies the type of memory device */
|
||||
u32 memory_type;
|
||||
|
||||
/* MC/EMC clock source configuration */
|
||||
|
||||
/* Specifies the M value for PllM */
|
||||
u32 pllm_input_divider;
|
||||
/* Specifies the N value for PllM */
|
||||
u32 pllm_feedback_divider;
|
||||
/* Specifies the time to wait for PLLM to lock (in microseconds) */
|
||||
u32 pllm_stable_time;
|
||||
/* Specifies misc. control bits */
|
||||
u32 pllm_setup_control;
|
||||
/* Specifies the P value for PLLM */
|
||||
u32 pllm_post_divider;
|
||||
/* Specifies value for Charge Pump Gain Control */
|
||||
u32 pllm_kcp;
|
||||
/* Specifies VCO gain */
|
||||
u32 pllm_kvco;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare0;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare1;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare2;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare3;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare4;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare5;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare6;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare7;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare8;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare9;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare10;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare11;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare12;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare13;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure0;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure1;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure2;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure3;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure4;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure5;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure6;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure7;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure8;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure9;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure10;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure11;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure12;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure13;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure14;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure15;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure16;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure17;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure18;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure19;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure20;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure21;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure22;
|
||||
/* Spare BCT param */
|
||||
u32 emc_bct_spare_secure23;
|
||||
|
||||
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
|
||||
u32 emc_clock_source;
|
||||
u32 emc_clock_source_dll;
|
||||
|
||||
/* Defines possible override for PLLLM_MISC2 */
|
||||
u32 clk_rst_pllm_misc20_override;
|
||||
/* enables override for PLLLM_MISC2 */
|
||||
u32 clk_rst_pllm_misc20_override_enable;
|
||||
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
|
||||
u32 clear_clock2_mc1;
|
||||
|
||||
/* Auto-calibration of EMC pads */
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
|
||||
u32 emc_auto_cal_interval;
|
||||
/*
|
||||
* Specifies the value for EMC_AUTO_CAL_CONFIG
|
||||
* Note: Trigger bits are set by the SDRAM code.
|
||||
*/
|
||||
u32 emc_auto_cal_config;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
|
||||
u32 emc_auto_cal_config2;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
|
||||
u32 emc_auto_cal_config3;
|
||||
u32 emc_auto_cal_config4;
|
||||
u32 emc_auto_cal_config5;
|
||||
u32 emc_auto_cal_config6;
|
||||
u32 emc_auto_cal_config7;
|
||||
u32 emc_auto_cal_config8;
|
||||
u32 emc_auto_cal_config9;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
|
||||
u32 emc_auto_cal_vref_sel0;
|
||||
u32 emc_auto_cal_vref_sel1;
|
||||
|
||||
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
|
||||
u32 emc_auto_cal_channel;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
|
||||
u32 emc_pmacro_auto_cal_cfg0;
|
||||
u32 emc_pmacro_auto_cal_cfg1;
|
||||
u32 emc_pmacro_auto_cal_cfg2;
|
||||
|
||||
u32 emc_pmacro_rx_term;
|
||||
u32 emc_pmacro_dq_tx_drive;
|
||||
u32 emc_pmacro_ca_tx_drive;
|
||||
u32 emc_pmacro_cmd_tx_drive;
|
||||
u32 emc_pmacro_auto_cal_common;
|
||||
u32 emc_pmacro_zcrtl;
|
||||
|
||||
/*
|
||||
* Specifies the time for the calibration
|
||||
* to stabilize (in microseconds)
|
||||
*/
|
||||
u32 emc_auto_cal_wait;
|
||||
|
||||
u32 emc_xm2_comp_pad_ctrl;
|
||||
u32 emc_xm2_comp_pad_ctrl2;
|
||||
u32 emc_xm2_comp_pad_ctrl3;
|
||||
|
||||
/*
|
||||
* DRAM size information
|
||||
* Specifies the value for EMC_ADR_CFG
|
||||
*/
|
||||
u32 emc_adr_cfg;
|
||||
|
||||
/*
|
||||
* Specifies the time to wait after asserting pin
|
||||
* CKE (in microseconds)
|
||||
*/
|
||||
u32 emc_pin_program_wait;
|
||||
/* Specifies the extra delay before/after pin RESET/CKE command */
|
||||
u32 emc_pin_extra_wait;
|
||||
|
||||
u32 emc_pin_gpio_enable;
|
||||
u32 emc_pin_gpio;
|
||||
|
||||
/*
|
||||
* Specifies the extra delay after the first writing
|
||||
* of EMC_TIMING_CONTROL
|
||||
*/
|
||||
u32 emc_timing_control_wait;
|
||||
|
||||
/* Timing parameters required for the SDRAM */
|
||||
|
||||
/* Specifies the value for EMC_RC */
|
||||
u32 emc_rc;
|
||||
/* Specifies the value for EMC_RFC */
|
||||
u32 emc_rfc;
|
||||
|
||||
u32 emc_rfc_pb;
|
||||
u32 emc_ref_ctrl2;
|
||||
|
||||
/* Specifies the value for EMC_RFC_SLR */
|
||||
u32 emc_rfc_slr;
|
||||
/* Specifies the value for EMC_RAS */
|
||||
u32 emc_ras;
|
||||
/* Specifies the value for EMC_RP */
|
||||
u32 emc_rp;
|
||||
/* Specifies the value for EMC_R2R */
|
||||
u32 emc_r2r;
|
||||
/* Specifies the value for EMC_W2W */
|
||||
u32 emc_w2w;
|
||||
/* Specifies the value for EMC_R2W */
|
||||
u32 emc_r2w;
|
||||
/* Specifies the value for EMC_W2R */
|
||||
u32 emc_w2r;
|
||||
/* Specifies the value for EMC_R2P */
|
||||
u32 emc_r2p;
|
||||
/* Specifies the value for EMC_W2P */
|
||||
u32 emc_w2p;
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
|
||||
u32 emc_tppd;
|
||||
u32 emc_trtm;
|
||||
u32 emc_twtm;
|
||||
u32 emc_tratm;
|
||||
u32 emc_twatm;
|
||||
u32 emc_tr2ref;
|
||||
u32 emc_ccdmw;
|
||||
|
||||
u32 emc_rd_rcd;
|
||||
/* Specifies the value for EMC_WR_RCD */
|
||||
u32 emc_wr_rcd;
|
||||
/* Specifies the value for EMC_RRD */
|
||||
u32 emc_rrd;
|
||||
/* Specifies the value for EMC_REXT */
|
||||
u32 emc_rext;
|
||||
/* Specifies the value for EMC_WEXT */
|
||||
u32 emc_wext;
|
||||
/* Specifies the value for EMC_WDV */
|
||||
u32 emc_wdv;
|
||||
|
||||
u32 emc_wdv_chk;
|
||||
u32 emc_wsv;
|
||||
u32 emc_wev;
|
||||
|
||||
/* Specifies the value for EMC_WDV_MASK */
|
||||
u32 emc_wdv_mask;
|
||||
|
||||
u32 emc_ws_duration;
|
||||
u32 emc_we_duration;
|
||||
|
||||
/* Specifies the value for EMC_QUSE */
|
||||
u32 emc_quse;
|
||||
/* Specifies the value for EMC_QUSE_WIDTH */
|
||||
u32 emc_quse_width;
|
||||
/* Specifies the value for EMC_IBDLY */
|
||||
u32 emc_ibdly;
|
||||
|
||||
u32 emc_obdly;
|
||||
|
||||
/* Specifies the value for EMC_EINPUT */
|
||||
u32 emc_einput;
|
||||
/* Specifies the value for EMC_EINPUT_DURATION */
|
||||
u32 emc_einput_duration;
|
||||
/* Specifies the value for EMC_PUTERM_EXTRA */
|
||||
u32 emc_puterm_extra;
|
||||
/* Specifies the value for EMC_PUTERM_WIDTH */
|
||||
u32 emc_puterm_width;
|
||||
|
||||
u32 emc_qrst;
|
||||
u32 emc_qsafe;
|
||||
u32 emc_rdv;
|
||||
u32 emc_rdv_mask;
|
||||
|
||||
u32 emc_rdv_early;
|
||||
u32 emc_rdv_early_mask;
|
||||
|
||||
/* Specifies the value for EMC_QPOP */
|
||||
u32 emc_qpop;
|
||||
|
||||
/* Specifies the value for EMC_REFRESH */
|
||||
u32 emc_refresh;
|
||||
/* Specifies the value for EMC_BURST_REFRESH_NUM */
|
||||
u32 emc_burst_refresh_num;
|
||||
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
|
||||
u32 emc_prerefresh_req_cnt;
|
||||
/* Specifies the value for EMC_PDEX2WR */
|
||||
u32 emc_pdex2wr;
|
||||
/* Specifies the value for EMC_PDEX2RD */
|
||||
u32 emc_pdex2rd;
|
||||
/* Specifies the value for EMC_PCHG2PDEN */
|
||||
u32 emc_pchg2pden;
|
||||
/* Specifies the value for EMC_ACT2PDEN */
|
||||
u32 emc_act2pden;
|
||||
/* Specifies the value for EMC_AR2PDEN */
|
||||
u32 emc_ar2pden;
|
||||
/* Specifies the value for EMC_RW2PDEN */
|
||||
u32 emc_rw2pden;
|
||||
|
||||
u32 emc_cke2pden;
|
||||
u32 emc_pdex2che;
|
||||
u32 emc_pdex2mrr;
|
||||
|
||||
/* Specifies the value for EMC_TXSR */
|
||||
u32 emc_txsr;
|
||||
/* Specifies the value for EMC_TXSRDLL */
|
||||
u32 emc_txsr_dll;
|
||||
/* Specifies the value for EMC_TCKE */
|
||||
u32 emc_tcke;
|
||||
/* Specifies the value for EMC_TCKESR */
|
||||
u32 emc_tckesr;
|
||||
/* Specifies the value for EMC_TPD */
|
||||
u32 emc_tpd;
|
||||
/* Specifies the value for EMC_TFAW */
|
||||
u32 emc_tfaw;
|
||||
/* Specifies the value for EMC_TRPAB */
|
||||
u32 emc_trpab;
|
||||
/* Specifies the value for EMC_TCLKSTABLE */
|
||||
u32 emc_tclkstable;
|
||||
/* Specifies the value for EMC_TCLKSTOP */
|
||||
u32 emc_tclkstop;
|
||||
/* Specifies the value for EMC_TREFBW */
|
||||
u32 emc_trefbw;
|
||||
|
||||
/* FBIO configuration values */
|
||||
|
||||
/* Specifies the value for EMC_FBIO_CFG5 */
|
||||
u32 emc_fbio_cfg5;
|
||||
/* Specifies the value for EMC_FBIO_CFG7 */
|
||||
u32 emc_fbio_cfg7;
|
||||
u32 emc_fbio_cfg8;
|
||||
|
||||
/* Command mapping for CMD brick 0 */
|
||||
u32 emc_cmd_mapping_cmd0_0;
|
||||
u32 emc_cmd_mapping_cmd0_1;
|
||||
u32 emc_cmd_mapping_cmd0_2;
|
||||
u32 emc_cmd_mapping_cmd1_0;
|
||||
u32 emc_cmd_mapping_cmd1_1;
|
||||
u32 emc_cmd_mapping_cmd1_2;
|
||||
u32 emc_cmd_mapping_cmd2_0;
|
||||
u32 emc_cmd_mapping_cmd2_1;
|
||||
u32 emc_cmd_mapping_cmd2_2;
|
||||
u32 emc_cmd_mapping_cmd3_0;
|
||||
u32 emc_cmd_mapping_cmd3_1;
|
||||
u32 emc_cmd_mapping_cmd3_2;
|
||||
u32 emc_cmd_mapping_byte;
|
||||
|
||||
/* Specifies the value for EMC_FBIO_SPARE */
|
||||
u32 emc_fbio_spare;
|
||||
|
||||
/* Specifies the value for EMC_CFG_RSV */
|
||||
u32 emc_cfg_rsv;
|
||||
|
||||
/* MRS command values */
|
||||
|
||||
/* Specifies the value for EMC_MRS */
|
||||
u32 emc_mrs;
|
||||
/* Specifies the MP0 command to initialize mode registers */
|
||||
u32 emc_emrs;
|
||||
/* Specifies the MP2 command to initialize mode registers */
|
||||
u32 emc_emrs2;
|
||||
/* Specifies the MP3 command to initialize mode registers */
|
||||
u32 emc_emrs3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
|
||||
u32 emc_mrw1;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
|
||||
u32 emc_mrw2;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
|
||||
u32 emc_mrw3;
|
||||
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
|
||||
u32 emc_mrw4;
|
||||
|
||||
/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
|
||||
u32 emc_mrw6;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
|
||||
u32 emc_mrw8;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
|
||||
u32 emc_mrw9;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
|
||||
u32 emc_mrw10;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
|
||||
u32 emc_mrw12;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
|
||||
u32 emc_mrw13;
|
||||
/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
|
||||
u32 emc_mrw14;
|
||||
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at cold boot
|
||||
*/
|
||||
u32 emc_mrw_extra;
|
||||
/*
|
||||
* Specifies the programming to extra LPDDR2 Mode Register
|
||||
* at warm boot
|
||||
*/
|
||||
u32 emc_warm_boot_mrw_extra;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* warm boot
|
||||
*/
|
||||
u32 emc_warm_boot_extramode_reg_write_enable;
|
||||
/*
|
||||
* Specify the enable of extra Mode Register programming at
|
||||
* cold boot
|
||||
*/
|
||||
u32 emc_extramode_reg_write_enable;
|
||||
|
||||
/* Specifies the EMC_MRW reset command value */
|
||||
u32 emc_mrw_reset_command;
|
||||
/* Specifies the EMC Reset wait time (in microseconds) */
|
||||
u32 emc_mrw_reset_ninit_wait;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT */
|
||||
u32 emc_mrs_wait_cnt;
|
||||
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
|
||||
u32 emc_mrs_wait_cnt2;
|
||||
|
||||
/* EMC miscellaneous configurations */
|
||||
|
||||
/* Specifies the value for EMC_CFG */
|
||||
u32 emc_cfg;
|
||||
/* Specifies the value for EMC_CFG_2 */
|
||||
u32 emc_cfg2;
|
||||
/* Specifies the pipe bypass controls */
|
||||
u32 emc_cfg_pipe;
|
||||
|
||||
u32 emc_cfg_pipe_clk;
|
||||
u32 emc_fdpd_ctrl_cmd_no_ramp;
|
||||
u32 emc_cfg_update;
|
||||
|
||||
/* Specifies the value for EMC_DBG */
|
||||
u32 emc_dbg;
|
||||
|
||||
u32 emc_dbg_write_mux;
|
||||
|
||||
/* Specifies the value for EMC_CMDQ */
|
||||
u32 emc_cmd_q;
|
||||
/* Specifies the value for EMC_MC2EMCQ */
|
||||
u32 emc_mc2emc_q;
|
||||
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
|
||||
u32 emc_dyn_self_ref_control;
|
||||
|
||||
/* Specifies the value for MEM_INIT_DONE */
|
||||
u32 ahb_arbitration_xbar_ctrl_meminit_done;
|
||||
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL */
|
||||
u32 emc_cfg_dig_dll;
|
||||
u32 emc_cfg_dig_dll_1;
|
||||
|
||||
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
|
||||
u32 emc_cfg_dig_dll_period;
|
||||
/* Specifies the value of *DEV_SELECTN of various EMC registers */
|
||||
u32 emc_dev_select;
|
||||
|
||||
/* Specifies the value for EMC_SEL_DPD_CTRL */
|
||||
u32 emc_sel_dpd_ctrl;
|
||||
|
||||
/* Pads trimmer delays */
|
||||
u32 emc_fdpd_ctrl_dq;
|
||||
u32 emc_fdpd_ctrl_cmd;
|
||||
u32 emc_pmacro_ib_vref_dq_0;
|
||||
u32 emc_pmacro_ib_vref_dq_1;
|
||||
u32 emc_pmacro_ib_vref_dqs_0;
|
||||
u32 emc_pmacro_ib_vref_dqs_1;
|
||||
u32 emc_pmacro_ib_rxrt;
|
||||
u32 emc_cfg_pipe1;
|
||||
u32 emc_cfg_pipe2;
|
||||
|
||||
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
|
||||
u32 emc_pmacro_quse_ddll_rank0_0;
|
||||
u32 emc_pmacro_quse_ddll_rank0_1;
|
||||
u32 emc_pmacro_quse_ddll_rank0_2;
|
||||
u32 emc_pmacro_quse_ddll_rank0_3;
|
||||
u32 emc_pmacro_quse_ddll_rank0_4;
|
||||
u32 emc_pmacro_quse_ddll_rank0_5;
|
||||
u32 emc_pmacro_quse_ddll_rank1_0;
|
||||
u32 emc_pmacro_quse_ddll_rank1_1;
|
||||
u32 emc_pmacro_quse_ddll_rank1_2;
|
||||
u32 emc_pmacro_quse_ddll_rank1_3;
|
||||
u32 emc_pmacro_quse_ddll_rank1_4;
|
||||
u32 emc_pmacro_quse_ddll_rank1_5;
|
||||
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_0;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_1;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_2;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_3;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_4;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank0_5;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_0;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_1;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_2;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_3;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_4;
|
||||
u32 emc_pmacro_ob_ddll_long_dq_rank1_5;
|
||||
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_0;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_1;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_2;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_3;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_4;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank0_5;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_0;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_1;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_2;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_3;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_4;
|
||||
u32 emc_pmacro_ob_ddll_long_dqs_rank1_5;
|
||||
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank0_0;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank0_1;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank0_2;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank0_3;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank1_0;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank1_1;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
||||
u32 emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
||||
|
||||
u32 emc_pmacro_ddll_long_cmd_0;
|
||||
u32 emc_pmacro_ddll_long_cmd_1;
|
||||
u32 emc_pmacro_ddll_long_cmd_2;
|
||||
u32 emc_pmacro_ddll_long_cmd_3;
|
||||
u32 emc_pmacro_ddll_long_cmd_4;
|
||||
u32 emc_pmacro_ddll_short_cmd_0;
|
||||
u32 emc_pmacro_ddll_short_cmd_1;
|
||||
u32 emc_pmacro_ddll_short_cmd_2;
|
||||
|
||||
u32 emc_pmacro_ddll_periodic_offset;
|
||||
|
||||
/*
|
||||
* Specifies the delay after asserting CKE pin during a WarmBoot0
|
||||
* sequence (in microseconds)
|
||||
*/
|
||||
u32 warm_boot_wait;
|
||||
|
||||
/* Specifies the value for EMC_ODT_WRITE */
|
||||
u32 emc_odt_write;
|
||||
|
||||
/* Periodic ZQ calibration */
|
||||
|
||||
/*
|
||||
* Specifies the value for EMC_ZCAL_INTERVAL
|
||||
* Value 0 disables ZQ calibration
|
||||
*/
|
||||
u32 emc_zcal_interval;
|
||||
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
|
||||
u32 emc_zcal_wait_cnt;
|
||||
/* Specifies the value for EMC_ZCAL_MRW_CMD */
|
||||
u32 emc_zcal_mrw_cmd;
|
||||
|
||||
/* DRAM initialization sequence flow control */
|
||||
|
||||
/* Specifies the MRS command value for resetting DLL */
|
||||
u32 emc_mrs_reset_dll;
|
||||
/* Specifies the command for ZQ initialization of device 0 */
|
||||
u32 emc_zcal_init_dev0;
|
||||
/* Specifies the command for ZQ initialization of device 1 */
|
||||
u32 emc_zcal_init_dev1;
|
||||
/*
|
||||
* Specifies the wait time after programming a ZQ initialization
|
||||
* command (in microseconds)
|
||||
*/
|
||||
u32 emc_zcal_init_wait;
|
||||
/*
|
||||
* Specifies the enable for ZQ calibration at cold boot [bit 0]
|
||||
* and warm boot [bit 1]
|
||||
*/
|
||||
u32 emc_zcal_warm_cold_boot_enables;
|
||||
|
||||
/*
|
||||
* Specifies the MRW command to LPDDR2 for ZQ calibration
|
||||
* on warmboot
|
||||
*/
|
||||
/* Is issued to both devices separately */
|
||||
u32 emc_mrw_lpddr2zcal_warm_boot;
|
||||
/*
|
||||
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
|
||||
* Is issued to both devices separately
|
||||
*/
|
||||
u32 emc_zqcal_ddr3_warm_boot;
|
||||
|
||||
u32 emc_zqcal_lpddr4_warm_boot;
|
||||
|
||||
/*
|
||||
* Specifies the wait time for ZQ calibration on warmboot
|
||||
* (in microseconds)
|
||||
*/
|
||||
u32 emc_zcal_warm_boot_wait;
|
||||
/*
|
||||
* Specifies the enable for DRAM Mode Register programming
|
||||
* at warm boot
|
||||
*/
|
||||
u32 emc_mrs_warm_boot_enable;
|
||||
/*
|
||||
* Specifies the wait time after sending an MRS DLL reset command
|
||||
* in microseconds)
|
||||
*/
|
||||
u32 emc_mrs_reset_dll_wait;
|
||||
/* Specifies the extra MRS command to initialize mode registers */
|
||||
u32 emc_mrs_extra;
|
||||
/* Specifies the extra MRS command at warm boot */
|
||||
u32 emc_warm_boot_mrs_extra;
|
||||
/* Specifies the EMRS command to enable the DDR2 DLL */
|
||||
u32 emc_emrs_ddr2_dll_enable;
|
||||
/* Specifies the MRS command to reset the DDR2 DLL */
|
||||
u32 emc_mrs_ddr2_dll_reset;
|
||||
/* Specifies the EMRS command to set OCD calibration */
|
||||
u32 emc_emrs_ddr2_ocd_calib;
|
||||
/*
|
||||
* Specifies the wait between initializing DDR and setting OCD
|
||||
* calibration (in microseconds)
|
||||
*/
|
||||
u32 emc_ddr2_wait;
|
||||
/* Specifies the value for EMC_CLKEN_OVERRIDE */
|
||||
u32 emc_clken_override;
|
||||
/*
|
||||
* Specifies LOG2 of the extra refresh numbers after booting
|
||||
* Program 0 to disable
|
||||
*/
|
||||
u32 emc_extra_refresh_num;
|
||||
/* Specifies the master override for all EMC clocks */
|
||||
u32 emc_clken_override_allwarm_boot;
|
||||
/* Specifies the master override for all MC clocks */
|
||||
u32 mc_clken_override_allwarm_boot;
|
||||
/* Specifies digital dll period, choosing between 4 to 64 ms */
|
||||
u32 emc_cfg_dig_dll_period_warm_boot;
|
||||
|
||||
/* Pad controls */
|
||||
|
||||
/* Specifies the value for PMC_VDDP_SEL */
|
||||
u32 pmc_vddp_sel;
|
||||
/* Specifies the wait time after programming PMC_VDDP_SEL */
|
||||
u32 pmc_vddp_sel_wait;
|
||||
/* Specifies the value for PMC_DDR_CFG */
|
||||
u32 pmc_ddr_cfg;
|
||||
/* Specifies the value for PMC_IO_DPD3_REQ */
|
||||
u32 pmc_io_dpd3_req;
|
||||
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
|
||||
u32 pmc_io_dpd3_req_wait;
|
||||
|
||||
u32 pmc_io_dpd4_req_wait;
|
||||
|
||||
/* Specifies the value for PMC_REG_SHORT */
|
||||
u32 pmc_reg_short;
|
||||
/* Specifies the value for PMC_NO_IOPOWER */
|
||||
u32 pmc_no_io_power;
|
||||
|
||||
u32 pmc_ddr_ctrl_wait;
|
||||
u32 pmc_ddr_ctrl;
|
||||
|
||||
/* Specifies the value for EMC_ACPD_CONTROL */
|
||||
u32 emc_acpd_control;
|
||||
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
|
||||
u32 emc_swizzle_rank0_byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
|
||||
u32 emc_swizzle_rank0_byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
|
||||
u32 emc_swizzle_rank0_byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
|
||||
u32 emc_swizzle_rank0_byte3;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
|
||||
u32 emc_swizzle_rank1_byte0;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
|
||||
u32 emc_swizzle_rank1_byte1;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
|
||||
u32 emc_swizzle_rank1_byte2;
|
||||
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
|
||||
u32 emc_swizzle_rank1_byte3;
|
||||
|
||||
/* Specifies the value for EMC_TXDSRVTTGEN */
|
||||
u32 emc_txdsrvttgen;
|
||||
|
||||
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
|
||||
u32 emc_data_brlshft0;
|
||||
u32 emc_data_brlshft1;
|
||||
|
||||
u32 emc_dqs_brlshft0;
|
||||
u32 emc_dqs_brlshft1;
|
||||
|
||||
u32 emc_cmd_brlshft0;
|
||||
u32 emc_cmd_brlshft1;
|
||||
u32 emc_cmd_brlshft2;
|
||||
u32 emc_cmd_brlshft3;
|
||||
|
||||
u32 emc_quse_brlshft0;
|
||||
u32 emc_quse_brlshft1;
|
||||
u32 emc_quse_brlshft2;
|
||||
u32 emc_quse_brlshft3;
|
||||
|
||||
u32 emc_dll_cfg0;
|
||||
u32 emc_dll_cfg1;
|
||||
|
||||
u32 emc_pmc_scratch1;
|
||||
u32 emc_pmc_scratch2;
|
||||
u32 emc_pmc_scratch3;
|
||||
|
||||
u32 emc_pmacro_pad_cfg_ctrl;
|
||||
|
||||
u32 emc_pmacro_vttgen_ctrl0;
|
||||
u32 emc_pmacro_vttgen_ctrl1;
|
||||
u32 emc_pmacro_vttgen_ctrl2;
|
||||
u32 emc_pmacro_dsr_vttgen_ctrl0;
|
||||
u32 emc_pmacro_brick_ctrl_rfu1;
|
||||
u32 emc_pmacro_cmd_brick_ctrl_fdpd;
|
||||
u32 emc_pmacro_brick_ctrl_rfu2;
|
||||
u32 emc_pmacro_data_brick_ctrl_fdpd;
|
||||
u32 emc_pmacro_bg_bias_ctrl0;
|
||||
u32 emc_pmacro_data_pad_rx_ctrl;
|
||||
u32 emc_pmacro_cmd_pad_rx_ctrl;
|
||||
u32 emc_pmacro_data_rx_term_mode;
|
||||
u32 emc_pmacro_cmd_rx_term_mode;
|
||||
u32 emc_pmacro_data_pad_tx_ctrl;
|
||||
u32 emc_pmacro_cmd_pad_tx_ctrl;
|
||||
u32 emc_cfg3;
|
||||
|
||||
u32 emc_pmacro_tx_pwrd0;
|
||||
u32 emc_pmacro_tx_pwrd1;
|
||||
u32 emc_pmacro_tx_pwrd2;
|
||||
u32 emc_pmacro_tx_pwrd3;
|
||||
u32 emc_pmacro_tx_pwrd4;
|
||||
u32 emc_pmacro_tx_pwrd5;
|
||||
|
||||
u32 emc_config_sample_delay;
|
||||
|
||||
u32 emc_pmacro_brick_mapping0;
|
||||
u32 emc_pmacro_brick_mapping1;
|
||||
u32 emc_pmacro_brick_mapping2;
|
||||
|
||||
u32 emc_pmacro_tx_sel_clk_src0;
|
||||
u32 emc_pmacro_tx_sel_clk_src1;
|
||||
u32 emc_pmacro_tx_sel_clk_src2;
|
||||
u32 emc_pmacro_tx_sel_clk_src3;
|
||||
u32 emc_pmacro_tx_sel_clk_src4;
|
||||
u32 emc_pmacro_tx_sel_clk_src5;
|
||||
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl0;
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl1;
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl2;
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl3;
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl4;
|
||||
u32 emc_pmacro_perbit_fgcg_ctrl5;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl0;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl1;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl2;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl3;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl4;
|
||||
u32 emc_pmacro_perbit_rfu_ctrl5;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl0;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl1;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl2;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl3;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl4;
|
||||
u32 emc_pmacro_perbit_rfu1_ctrl5;
|
||||
|
||||
u32 emc_pmacro_data_pi_ctrl;
|
||||
u32 emc_pmacro_cmd_pi_ctrl;
|
||||
|
||||
u32 emc_pmacro_ddll_bypass;
|
||||
|
||||
u32 emc_pmacro_ddll_pwrd0;
|
||||
u32 emc_pmacro_ddll_pwrd1;
|
||||
u32 emc_pmacro_ddll_pwrd2;
|
||||
|
||||
u32 emc_pmacro_cmd_ctrl0;
|
||||
u32 emc_pmacro_cmd_ctrl1;
|
||||
u32 emc_pmacro_cmd_ctrl2;
|
||||
|
||||
/* DRAM size information */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG */
|
||||
u32 mc_emem_adr_cfg;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
|
||||
u32 mc_emem_adr_cfg_dev0;
|
||||
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
|
||||
u32 mc_emem_adr_cfg_dev1;
|
||||
|
||||
u32 mc_emem_adr_cfg_channel_mask;
|
||||
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
|
||||
u32 mc_emem_adr_cfg_bank_mask0;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
|
||||
u32 mc_emem_adr_cfg_bank_mask1;
|
||||
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
|
||||
u32 mc_emem_adr_cfg_bank_mask2;
|
||||
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
*/
|
||||
u32 mc_emem_cfg;
|
||||
|
||||
/* MC arbitration configuration */
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_CFG */
|
||||
u32 mc_emem_arb_cfg;
|
||||
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
|
||||
u32 mc_emem_arb_outstanding_req;
|
||||
|
||||
u32 emc_emem_arb_refpb_hp_ctrl;
|
||||
u32 emc_emem_arb_refpb_bank_ctrl;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
|
||||
u32 mc_emem_arb_timing_rcd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
|
||||
u32 mc_emem_arb_timing_rp;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
|
||||
u32 mc_emem_arb_timing_rc;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
|
||||
u32 mc_emem_arb_timing_ras;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
|
||||
u32 mc_emem_arb_timing_faw;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
|
||||
u32 mc_emem_arb_timing_rrd;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
|
||||
u32 mc_emem_arb_timing_rap2pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
|
||||
u32 mc_emem_arb_timing_wap2pre;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
|
||||
u32 mc_emem_arb_timing_r2r;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
|
||||
u32 mc_emem_arb_timing_w2w;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
|
||||
u32 mc_emem_arb_timing_r2w;
|
||||
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
|
||||
u32 mc_emem_arb_timing_w2r;
|
||||
|
||||
u32 mc_emem_arb_timing_rfcpb;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
|
||||
u32 mc_emem_arb_da_turns;
|
||||
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
|
||||
u32 mc_emem_arb_da_covers;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC0 */
|
||||
u32 mc_emem_arb_misc0;
|
||||
/* Specifies the value for MC_EMEM_ARB_MISC1 */
|
||||
u32 mc_emem_arb_misc1;
|
||||
u32 mc_emem_arb_misc2;
|
||||
|
||||
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
|
||||
u32 mc_emem_arb_ring1_throttle;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
|
||||
u32 mc_emem_arb_override;
|
||||
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
|
||||
u32 mc_emem_arb_override1;
|
||||
/* Specifies the value for MC_EMEM_ARB_RSV */
|
||||
u32 mc_emem_arb_rsv;
|
||||
|
||||
u32 mc_da_cfg0;
|
||||
u32 mc_emem_arb_timing_ccdmw;
|
||||
|
||||
/* Specifies the value for MC_CLKEN_OVERRIDE */
|
||||
u32 mc_clken_override;
|
||||
|
||||
/* Specifies the value for MC_STAT_CONTROL */
|
||||
u32 mc_stat_control;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
|
||||
u32 mc_video_protect_bom;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
|
||||
u32 mc_video_protect_bom_adr_hi;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
|
||||
u32 mc_video_protect_size_mb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
|
||||
u32 mc_video_protect_vpr_override;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
|
||||
u32 mc_video_protect_vpr_override1;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
|
||||
u32 mc_video_protect_gpu_override0;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
|
||||
u32 mc_video_protect_gpu_override1;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
|
||||
u32 mc_sec_carveout_bom;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
|
||||
u32 mc_sec_carveout_adr_hi;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
|
||||
u32 mc_sec_carveout_size_mb;
|
||||
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
|
||||
u32 mc_video_protect_write_access;
|
||||
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
|
||||
u32 mc_sec_carveout_protect_write_access;
|
||||
|
||||
u32 mc_generalized_carveout1_bom;
|
||||
u32 mc_generalized_carveout1_bom_hi;
|
||||
u32 mc_generalized_carveout1_size_128kb;
|
||||
u32 mc_generalized_carveout1_access0;
|
||||
u32 mc_generalized_carveout1_access1;
|
||||
u32 mc_generalized_carveout1_access2;
|
||||
u32 mc_generalized_carveout1_access3;
|
||||
u32 mc_generalized_carveout1_access4;
|
||||
u32 mc_generalized_carveout1_force_internal_access0;
|
||||
u32 mc_generalized_carveout1_force_internal_access1;
|
||||
u32 mc_generalized_carveout1_force_internal_access2;
|
||||
u32 mc_generalized_carveout1_force_internal_access3;
|
||||
u32 mc_generalized_carveout1_force_internal_access4;
|
||||
u32 mc_generalized_carveout1_cfg0;
|
||||
|
||||
u32 mc_generalized_carveout2_bom;
|
||||
u32 mc_generalized_carveout2_bom_hi;
|
||||
u32 mc_generalized_carveout2_size_128kb;
|
||||
u32 mc_generalized_carveout2_access0;
|
||||
u32 mc_generalized_carveout2_access1;
|
||||
u32 mc_generalized_carveout2_access2;
|
||||
u32 mc_generalized_carveout2_access3;
|
||||
u32 mc_generalized_carveout2_access4;
|
||||
u32 mc_generalized_carveout2_force_internal_access0;
|
||||
u32 mc_generalized_carveout2_force_internal_access1;
|
||||
u32 mc_generalized_carveout2_force_internal_access2;
|
||||
u32 mc_generalized_carveout2_force_internal_access3;
|
||||
u32 mc_generalized_carveout2_force_internal_access4;
|
||||
u32 mc_generalized_carveout2_cfg0;
|
||||
|
||||
u32 mc_generalized_carveout3_bom;
|
||||
u32 mc_generalized_carveout3_bom_hi;
|
||||
u32 mc_generalized_carveout3_size_128kb;
|
||||
u32 mc_generalized_carveout3_access0;
|
||||
u32 mc_generalized_carveout3_access1;
|
||||
u32 mc_generalized_carveout3_access2;
|
||||
u32 mc_generalized_carveout3_access3;
|
||||
u32 mc_generalized_carveout3_access4;
|
||||
u32 mc_generalized_carveout3_force_internal_access0;
|
||||
u32 mc_generalized_carveout3_force_internal_access1;
|
||||
u32 mc_generalized_carveout3_force_internal_access2;
|
||||
u32 mc_generalized_carveout3_force_internal_access3;
|
||||
u32 mc_generalized_carveout3_force_internal_access4;
|
||||
u32 mc_generalized_carveout3_cfg0;
|
||||
|
||||
u32 mc_generalized_carveout4_bom;
|
||||
u32 mc_generalized_carveout4_bom_hi;
|
||||
u32 mc_generalized_carveout4_size_128kb;
|
||||
u32 mc_generalized_carveout4_access0;
|
||||
u32 mc_generalized_carveout4_access1;
|
||||
u32 mc_generalized_carveout4_access2;
|
||||
u32 mc_generalized_carveout4_access3;
|
||||
u32 mc_generalized_carveout4_access4;
|
||||
u32 mc_generalized_carveout4_force_internal_access0;
|
||||
u32 mc_generalized_carveout4_force_internal_access1;
|
||||
u32 mc_generalized_carveout4_force_internal_access2;
|
||||
u32 mc_generalized_carveout4_force_internal_access3;
|
||||
u32 mc_generalized_carveout4_force_internal_access4;
|
||||
u32 mc_generalized_carveout4_cfg0;
|
||||
|
||||
u32 mc_generalized_carveout5_bom;
|
||||
u32 mc_generalized_carveout5_bom_hi;
|
||||
u32 mc_generalized_carveout5_size_128kb;
|
||||
u32 mc_generalized_carveout5_access0;
|
||||
u32 mc_generalized_carveout5_access1;
|
||||
u32 mc_generalized_carveout5_access2;
|
||||
u32 mc_generalized_carveout5_access3;
|
||||
u32 mc_generalized_carveout5_access4;
|
||||
u32 mc_generalized_carveout5_force_internal_access0;
|
||||
u32 mc_generalized_carveout5_force_internal_access1;
|
||||
u32 mc_generalized_carveout5_force_internal_access2;
|
||||
u32 mc_generalized_carveout5_force_internal_access3;
|
||||
u32 mc_generalized_carveout5_force_internal_access4;
|
||||
u32 mc_generalized_carveout5_cfg0;
|
||||
|
||||
/* Specifies enable for CA training */
|
||||
u32 emc_ca_training_enable;
|
||||
/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
|
||||
u32 swizzle_rank_byte_encode;
|
||||
/* Specifies enable and offset for patched boot rom write */
|
||||
u32 boot_rom_patch_control;
|
||||
/* Specifies data for patched boot rom write */
|
||||
u32 boot_rom_patch_data;
|
||||
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
|
||||
u32 mc_mts_carveout_bom;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
|
||||
u32 mc_mts_carveout_adr_hi;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
|
||||
u32 mc_mts_carveout_size_mb;
|
||||
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
|
||||
u32 mc_mts_carveout_reg_ctrl;
|
||||
|
||||
u32 mc_untranslated_region_check;
|
||||
|
||||
/* Just a place holder for special usage when there is no BCT for certain registers */
|
||||
u32 bct_na;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
|
|||
u32 emc_r2p;
|
||||
/* Specifies the value for EMC_W2P */
|
||||
u32 emc_w2p;
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
|
||||
u32 emc_tppd;
|
||||
u32 emc_trtm;
|
||||
|
@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
|
|||
u32 emc_tr2ref;
|
||||
u32 emc_ccdmw;
|
||||
|
||||
/* Specifies the value for EMC_RD_RCD */
|
||||
u32 emc_rd_rcd;
|
||||
/* Specifies the value for EMC_WR_RCD */
|
||||
u32 emc_wr_rcd;
|
||||
|
|
238
bdk/mem/smmu.c
238
bdk/mem/smmu.c
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,155 +18,228 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc_t210.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/util.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
#include <memory_map.h>
|
||||
|
||||
bool smmu_used = false;
|
||||
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;
|
||||
/*! SMMU register defines */
|
||||
#define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
|
||||
#define SMMU_ENABLE BIT(31)
|
||||
#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
|
||||
#define SMMU_TLB_RR_ARBITRATION BIT(28)
|
||||
#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
|
||||
#define SMMU_TLB_STATS_ENABLE BIT(31)
|
||||
#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
|
||||
#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
|
||||
#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
|
||||
#define SMUU_PTC_CACHE_ENABLE BIT(29)
|
||||
#define SMUU_PTC_STATS_ENABLE BIT(31)
|
||||
|
||||
//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;
|
||||
u8 smmu_payload[] __attribute__((aligned(16))) = {
|
||||
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010
|
||||
/*! Page table defines */
|
||||
#define SMMU_4MB_REGION 0
|
||||
#define SMMU_PAGE_TABLE 1
|
||||
#define SMMU_PDIR_COUNT 1024
|
||||
#define SMMU_PTBL_COUNT 1024
|
||||
#define SMMU_PAGE_SHIFT 12u
|
||||
#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
|
||||
#define SMMU_PDN_SHIFT 22u
|
||||
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
|
||||
#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
|
||||
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
|
||||
#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
|
||||
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
|
||||
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
|
||||
|
||||
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
|
||||
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
|
||||
static const u8 smmu_enable_payload[] = {
|
||||
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
|
||||
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
|
||||
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
|
||||
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
|
||||
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
|
||||
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
|
||||
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0
|
||||
0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
|
||||
0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
|
||||
0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
|
||||
0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
|
||||
0x00, 0x00, 0x00, 0x00, // 0x2C:
|
||||
0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
|
||||
0x00, 0x00, 0x00, 0x00 // 0x34:
|
||||
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
|
||||
};
|
||||
|
||||
void *page_alloc(u32 num)
|
||||
void *smmu_page_zalloc(u32 num)
|
||||
{
|
||||
u8 *res = _pageheap;
|
||||
_pageheap += 0x1000 * num;
|
||||
memset(res, 0, 0x1000 * num);
|
||||
return res;
|
||||
void *page = smmu_heap;
|
||||
memset(page, 0, SZ_PAGE * num);
|
||||
|
||||
smmu_heap += SZ_PAGE * num;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
u32 *smmu_alloc_pdir()
|
||||
static pde_t *_smmu_pdir_alloc()
|
||||
{
|
||||
u32 *pdir = (u32 *)page_alloc(1);
|
||||
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
||||
pdir[pdn] = _PDE_VACANT(pdn);
|
||||
pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
|
||||
|
||||
// Initialize pdes with no permissions.
|
||||
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
|
||||
pdir[pdn].huge.page = pdn;
|
||||
|
||||
return pdir;
|
||||
}
|
||||
|
||||
void smmu_flush_regs()
|
||||
static void _smmu_flush_regs()
|
||||
{
|
||||
(void)MC(MC_SMMU_PTB_DATA);
|
||||
}
|
||||
|
||||
void smmu_flush_all()
|
||||
{
|
||||
|
||||
// Flush the entire page table cache.
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
smmu_flush_regs();
|
||||
_smmu_flush_regs();
|
||||
|
||||
// Flush the entire table.
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
smmu_flush_regs();
|
||||
_smmu_flush_regs();
|
||||
}
|
||||
|
||||
void smmu_init(u32 secmon_base)
|
||||
void smmu_init()
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = 0;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
|
||||
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
|
||||
// Set the secmon address
|
||||
*(u32 *)(smmu_payload + 0x30) = secmon_base;
|
||||
MC(MC_SMMU_PTB_ASID) = 0;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
|
||||
MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
}
|
||||
|
||||
void smmu_enable()
|
||||
{
|
||||
if (smmu_used)
|
||||
static bool enabled = false;
|
||||
|
||||
if (enabled)
|
||||
return;
|
||||
|
||||
ccplex_boot_cpu0((u32)smmu_payload);
|
||||
smmu_used = true;
|
||||
msleep(150);
|
||||
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
|
||||
msleep(100);
|
||||
ccplex_powergate_cpu0();
|
||||
|
||||
smmu_flush_all();
|
||||
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
bool smmu_is_used()
|
||||
void smmu_reset_heap()
|
||||
{
|
||||
return smmu_used;
|
||||
smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
}
|
||||
|
||||
void smmu_exit()
|
||||
void *smmu_init_domain(u32 dev_base, u32 asid)
|
||||
{
|
||||
*(u32 *)(smmu_payload + 0x14) = _NOP();
|
||||
}
|
||||
|
||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
||||
{
|
||||
u32 *pdir = smmu_alloc_pdir();
|
||||
void *ptb = _smmu_pdir_alloc();
|
||||
|
||||
MC(MC_SMMU_PTB_ASID) = asid;
|
||||
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);
|
||||
smmu_flush_regs();
|
||||
MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
|
||||
_smmu_flush_regs();
|
||||
|
||||
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);
|
||||
smmu_flush_regs();
|
||||
// Use the same macro for both quad and single domains. Reserved bits are not set anyway.
|
||||
MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
|
||||
_smmu_flush_regs();
|
||||
|
||||
return pdir;
|
||||
return ptb;
|
||||
}
|
||||
|
||||
u32 *smmu_get_pte(u32 *pdir, u32 iova)
|
||||
void smmu_deinit_domain(u32 dev_base, u32 asid)
|
||||
{
|
||||
u32 ptn = SMMU_ADDR_TO_PFN(iova);
|
||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||
u32 *ptbl;
|
||||
MC(MC_SMMU_PTB_ASID) = asid;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(dev_base) = 0;
|
||||
_smmu_flush_regs();
|
||||
}
|
||||
|
||||
if (pdir[pdn] != _PDE_VACANT(pdn))
|
||||
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);
|
||||
void smmu_domain_bypass(u32 dev_base, bool bypass)
|
||||
{
|
||||
if (bypass)
|
||||
{
|
||||
smmu_flush_all();
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
MC(dev_base) &= ~SMMU_ENABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptbl = (u32 *)page_alloc(1);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
MC(dev_base) |= SMMU_ENABLE;
|
||||
smmu_flush_all();
|
||||
}
|
||||
_smmu_flush_regs();
|
||||
}
|
||||
|
||||
static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
|
||||
{
|
||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||
pte_t *ptbl;
|
||||
|
||||
// Get 4MB page table or initialize one.
|
||||
if (pdir[pdn].tbl.attr)
|
||||
ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
|
||||
else
|
||||
{
|
||||
// Allocate page table.
|
||||
ptbl = (pte_t *)smmu_page_zalloc(1);
|
||||
|
||||
// Get address.
|
||||
u32 addr = SMMU_PDN_TO_ADDR(pdn);
|
||||
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
|
||||
ptbl[pn] = _PTE_VACANT(addr);
|
||||
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);
|
||||
|
||||
// Initialize page table with no permissions.
|
||||
for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
|
||||
ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
|
||||
|
||||
// Set page table to the page directory.
|
||||
pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
|
||||
pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
|
||||
pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
|
||||
|
||||
smmu_flush_all();
|
||||
}
|
||||
|
||||
return &ptbl[ptn % SMMU_PTBL_COUNT];
|
||||
return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
|
||||
}
|
||||
|
||||
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)
|
||||
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
// Map pages to page table entries. VA/PA should be aligned to 4KB.
|
||||
for (u32 i = 0; i < pages; i++)
|
||||
{
|
||||
u32 *pte = smmu_get_pte(pdir, addr);
|
||||
*pte = SMMU_ADDR_TO_PFN(page) | attr;
|
||||
addr += 0x1000;
|
||||
page += 0x1000;
|
||||
pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
|
||||
|
||||
pte->page = SMMU_ADDR_TO_PFN(iopa);
|
||||
pte->attr = attr;
|
||||
|
||||
iova += SZ_PAGE;
|
||||
iopa += SZ_PAGE;
|
||||
}
|
||||
|
||||
smmu_flush_all();
|
||||
}
|
||||
|
||||
u32 *smmu_init_for_tsec()
|
||||
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
|
||||
{
|
||||
return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);
|
||||
}
|
||||
pde_t *pdir = (pde_t *)ptb;
|
||||
|
||||
void smmu_deinit_for_tsec()
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = 1;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TSEC_ASID) = 0;
|
||||
smmu_flush_regs();
|
||||
}
|
||||
// Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
|
||||
for (u32 i = 0; i < regions; i++)
|
||||
{
|
||||
u32 pdn = SMMU_ADDR_TO_PDN(iova);
|
||||
pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
|
||||
pdir[pdn].huge.next = SMMU_4MB_REGION;
|
||||
pdir[pdn].huge.attr = attr;
|
||||
|
||||
iova += SZ_4M;
|
||||
iopa += SZ_4M;
|
||||
}
|
||||
|
||||
smmu_flush_all();
|
||||
}
|
||||
|
|
111
bdk/mem/smmu.h
111
bdk/mem/smmu.h
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -14,69 +15,57 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define SMMU_HEAP_ADDR 0xA0000000
|
||||
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
#define MC_ERR_ADR 0xc
|
||||
#define MC_SMMU_CONFIG 0x10
|
||||
#define MC_SMMU_TLB_CONFIG 0x14
|
||||
#define MC_SMMU_PTC_CONFIG 0x18
|
||||
#define MC_SMMU_PTB_ASID 0x1c
|
||||
#define MC_SMMU_PTB_DATA 0x20
|
||||
#define MC_SMMU_TLB_FLUSH 0x30
|
||||
#define MC_SMMU_PTC_FLUSH 0x34
|
||||
#define MC_SMMU_ASID_SECURITY 0x38
|
||||
#define MC_SMMU_AVPC_ASID 0x23C
|
||||
#define MC_SMMU_TSEC_ASID 0x294
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
||||
|
||||
#define SMMU_PDE_NEXT_SHIFT 28
|
||||
#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
|
||||
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
|
||||
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
|
||||
#define SMMU_PAGE_SHIFT 12
|
||||
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
|
||||
#define SMMU_PDIR_COUNT 1024
|
||||
#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
|
||||
#define SMMU_PTBL_COUNT 1024
|
||||
#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
|
||||
#define SMMU_PDIR_SHIFT 12
|
||||
#define SMMU_PDE_SHIFT 12
|
||||
#define SMMU_PTE_SHIFT 12
|
||||
#define SMMU_PFN_MASK 0x000FFFFF
|
||||
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
|
||||
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
|
||||
#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
|
||||
#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
|
||||
#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
|
||||
#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
|
||||
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
|
||||
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
||||
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
||||
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
||||
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
|
||||
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
|
||||
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
|
||||
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
|
||||
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
|
||||
#define SMMU_NS BIT(0)
|
||||
#define SMMU_WRITE BIT(1)
|
||||
#define SMMU_READ BIT(2)
|
||||
#define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
|
||||
|
||||
void *page_alloc(u32 num);
|
||||
u32 *smmu_alloc_pdir();
|
||||
void smmu_flush_regs();
|
||||
void smmu_flush_all();
|
||||
void smmu_init(u32 secmon_base);
|
||||
void smmu_enable();
|
||||
bool smmu_is_used();
|
||||
void smmu_exit();
|
||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid);
|
||||
u32 *smmu_get_pte(u32 *pdir, u32 iova);
|
||||
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);
|
||||
u32 *smmu_init_for_tsec();
|
||||
void smmu_deinit_for_tsec();
|
||||
typedef struct _pde_t {
|
||||
union {
|
||||
union {
|
||||
struct {
|
||||
u32 table:22;
|
||||
u32 rsvd:6;
|
||||
u32 next:1;
|
||||
u32 attr:3;
|
||||
} tbl;
|
||||
|
||||
struct {
|
||||
u32 rsvd_:10;
|
||||
u32 page:12;
|
||||
u32 rsvd:6;
|
||||
u32 next:1;
|
||||
u32 attr:3;
|
||||
} huge;
|
||||
};
|
||||
|
||||
u32 pde;
|
||||
};
|
||||
} pde_t;
|
||||
|
||||
typedef struct _pte_t {
|
||||
u32 page:22;
|
||||
u32 rsvd:7;
|
||||
u32 attr:3;
|
||||
} pte_t;
|
||||
|
||||
static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
|
||||
static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
|
||||
|
||||
void *smmu_page_zalloc(u32 num);
|
||||
void smmu_flush_all();
|
||||
void smmu_init();
|
||||
void smmu_enable();
|
||||
void smmu_reset_heap();
|
||||
void *smmu_init_domain(u32 dev_base, u32 asid);
|
||||
void smmu_deinit_domain(u32 dev_base, u32 asid);
|
||||
void smmu_domain_bypass(u32 dev_base, bool bypass);
|
||||
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
|
||||
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,61 +17,76 @@
|
|||
#ifndef _MEMORY_MAP_H_
|
||||
#define _MEMORY_MAP_H_
|
||||
|
||||
//#define IPL_STACK_TOP 0x4003FF00
|
||||
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
||||
/* --- IPL: 0x40008000 - 0x40028000 --- */
|
||||
#define LDR_LOAD_ADDR 0x40007000
|
||||
|
||||
#define IPL_LOAD_ADDR 0x40008000
|
||||
#define IPL_SZ_MAX 0x20000 // 128KB.
|
||||
#define IPL_SZ_MAX SZ_128K
|
||||
|
||||
/* --- XUSB EP context and TRB ring buffers --- */
|
||||
#define XUSB_RING_ADDR 0x40020000
|
||||
#define XUSB_RING_ADDR 0x40020000 // XUSB EP context and TRB ring buffers.
|
||||
|
||||
#define SECMON_MIN_START 0x4002B000
|
||||
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
||||
|
||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||
|
||||
/* start.S / exception_handlers.S */
|
||||
#define SYS_STACK_TOP_INIT 0x4003FF00
|
||||
#define FIQ_STACK_TOP 0x40040000
|
||||
#define IRQ_STACK_TOP 0x40040000
|
||||
#define IPL_RELOC_ADDR 0x4003FF00
|
||||
#define IPL_RELOC_SZ 0x10
|
||||
#define EXCP_STORAGE_ADDR 0x4003FFF0
|
||||
#define EXCP_STORAGE_SZ 0x10
|
||||
|
||||
/* --- DRAM START --- */
|
||||
#define DRAM_START 0x80000000
|
||||
#define HOS_RSVD 0x1000000 // Do not write anything in this area.
|
||||
#define HOS_RSVD SZ_16M // Do not write anything in this area.
|
||||
|
||||
#define NYX_LOAD_ADDR 0x81000000
|
||||
#define NYX_SZ_MAX 0x1000000 // 16MB
|
||||
#define NYX_SZ_MAX SZ_16M
|
||||
/* --- Gap: 0x82000000 - 0x82FFFFFF --- */
|
||||
|
||||
/* Stack theoretical max: 33MB */
|
||||
#define IPL_STACK_TOP 0x83100000
|
||||
#define IPL_HEAP_START 0x84000000
|
||||
#define IPL_HEAP_SZ 0x20000000 // 512MB.
|
||||
#define IPL_HEAP_SZ (SZ_512M - SZ_64M)
|
||||
|
||||
#define SMMU_HEAP_ADDR 0xA0000000
|
||||
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
#define RAM_DISK_ADDR 0xA4000000
|
||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
||||
#define RAM_DISK2_SZ 0x21000000 // 528MB.
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xC5000000
|
||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||
#define NX_BIS_LOOKUP_ADDR 0xD6000000
|
||||
#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB.
|
||||
|
||||
// L4T Kernel Panic Storage (PSTORE).
|
||||
#define PSTORE_ADDR 0xB0000000
|
||||
#define PSTORE_SZ 0x200000 // 2MB.
|
||||
#define PSTORE_SZ SZ_2M
|
||||
|
||||
//#define DRAM_LIB_ADDR 0xE0000000
|
||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||
|
||||
// SDMMC DMA buffers 1
|
||||
#define SDMMC_UPPER_BUFFER 0xE5000000
|
||||
#define SDMMC_UP_BUF_SZ 0x8000000 // 128MB.
|
||||
#define SDMMC_UP_BUF_SZ SZ_128M
|
||||
|
||||
// Nyx buffers.
|
||||
#define NYX_STORAGE_ADDR 0xED000000
|
||||
#define NYX_RES_ADDR 0xEE000000
|
||||
#define NYX_RES_SZ 0x1000000 // 16MB.
|
||||
#define NYX_RES_SZ SZ_16M
|
||||
|
||||
// SDMMC DMA buffers 2
|
||||
#define SDXC_BUF_ALIGNED 0xEF000000
|
||||
#define MIXD_BUF_ALIGNED 0xF0000000
|
||||
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||
#define SDMMC_DMA_BUF_SZ 0x1000000 // 16MB (4MB currently used).
|
||||
#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
|
||||
|
||||
// Nyx LvGL buffers.
|
||||
#define NYX_LV_VDB_ADR 0xF1000000
|
||||
|
@ -88,22 +103,19 @@
|
|||
#define NYX_FB2_ADDRESS 0xF6600000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
|
||||
/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */
|
||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
||||
#define DRAM_START2 0xFEB40000
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xFEE00000
|
||||
#define NX_BIS_CACHE_SZ 0x100000
|
||||
|
||||
// USB buffers.
|
||||
#define USBD_ADDR 0xFEF00000
|
||||
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
||||
#define USB_EP_CONTROL_BUF_ADDR 0xFEF80000
|
||||
#define USB_EP_BULK_IN_BUF_ADDR 0xFF000000
|
||||
#define USB_EP_BULK_OUT_BUF_ADDR 0xFF800000
|
||||
#define USB_EP_BULK_OUT_MAX_XFER 0x800000
|
||||
#define USB_EP_BULK_OUT_MAX_XFER SZ_8M
|
||||
|
||||
// #define EXT_PAYLOAD_ADDR 0xC0000000
|
||||
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
#include <stddef.h>
|
||||
#include <mem/heap.h>
|
||||
|
||||
#define IANOS_EXT0 0x304E4149
|
||||
|
||||
// Module Callback
|
||||
typedef void (*cbMainModule_t)(const char *s);
|
||||
typedef void (*memcpy_t)(void *, void *, size_t);
|
||||
typedef void (*memset_t)(void *, int, size_t);
|
||||
typedef int (*reg_voltage_set_t)(u32, u32);
|
||||
|
||||
typedef struct _bdkParams_t
|
||||
{
|
||||
|
@ -33,6 +36,8 @@ typedef struct _bdkParams_t
|
|||
heap_t *sharedHeap;
|
||||
memcpy_t memcpy;
|
||||
memset_t memset;
|
||||
u32 extension_magic;
|
||||
reg_voltage_set_t reg_voltage_set;
|
||||
} *bdkParams_t;
|
||||
|
||||
// Module Entrypoint
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -73,18 +73,23 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
|||
|
||||
if (inserted)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = buf[0] & STATUS1_INSERT ? true : false;
|
||||
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||
memcpy(pdos, &buf[1], 28);
|
||||
|
||||
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
|
||||
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
|
||||
|
||||
if (usb_pd->pdo_no > 7)
|
||||
usb_pd->pdo_no = 7;
|
||||
|
||||
for (u32 i = 0; i < usb_pd->pdo_no; i++)
|
||||
{
|
||||
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// REG 1 masks.
|
||||
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) // 3000uV HOS default.
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1<<4)
|
||||
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "max17050.h"
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define BASE_SNS_UOHM 5000
|
||||
|
||||
|
@ -279,3 +279,26 @@ int max17050_fix_configuration()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void max17050_dump_regs(void *buf)
|
||||
{
|
||||
u16 *buff = (u16 *)buf;
|
||||
|
||||
// Unlock model table.
|
||||
u16 unlock = 0x59;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
|
||||
unlock = 0xC4;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
|
||||
|
||||
// Dump all battery fuel gauge registers.
|
||||
for (u32 i = 0; i < 0x100; i++)
|
||||
{
|
||||
buff[i] = max17050_get_reg(i);
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
// Lock model table.
|
||||
unlock = 0;
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
|
||||
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
|
||||
}
|
||||
|
|
|
@ -130,8 +130,9 @@ enum MAX17050_reg {
|
|||
MAX17050_VFSOC = 0xFF,
|
||||
};
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||
int max17050_fix_configuration();
|
||||
u32 max17050_get_cached_batt_volt();
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||
int max17050_fix_configuration();
|
||||
void max17050_dump_regs(void *buf);
|
||||
u32 max17050_get_cached_batt_volt();
|
||||
|
||||
#endif /* __MAX17050_H_ */
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/*
|
||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||
*
|
||||
* Copyright (c) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -30,24 +29,33 @@
|
|||
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST (BIT(5) | BIT(4))
|
||||
#define MAX77620_CNFGGLBL1_MPPLD BIT(6)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_EN BIT(7)
|
||||
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
#define MAX77620_WDTEN BIT(2)
|
||||
#define MAX77620_WDTSLPC BIT(3)
|
||||
#define MAX77620_WDTOFFC BIT(4)
|
||||
#define MAX77620_TWD_MASK 0x3
|
||||
#define MAX77620_TWD_2s 0x0
|
||||
#define MAX77620_TWD_16s 0x1
|
||||
#define MAX77620_TWD_64s 0x2
|
||||
#define MAX77620_TWD_128s 0x3
|
||||
#define MAX77620_WDTEN BIT(2)
|
||||
#define MAX77620_WDTSLPC BIT(3)
|
||||
#define MAX77620_WDTOFFC BIT(4)
|
||||
#define MAX77620_GLBL_LPM BIT(5)
|
||||
#define MAX77620_I2CTWD_MASK 0xC0
|
||||
#define MAX77620_I2CTWD_DISABLED 0x00
|
||||
#define MAX77620_I2CTWD_1_33ms 0x40
|
||||
#define MAX77620_I2CTWD_35_7ms 0x80
|
||||
#define MAX77620_I2CTWD_41_7ms 0xC0
|
||||
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
|
||||
#define MAX77620_REG_CNFG1_32K 0x03
|
||||
#define MAX77620_CNFG1_PWR_MD_32K_MASK 0x3
|
||||
#define MAX77620_CNFG1_32K_OUT0_EN BIT(2)
|
||||
#define MAX77620_CNFG1_32KLOAD_MASK 0x30
|
||||
#define MAX77620_CNFG1_32K_OK BIT(7)
|
||||
|
||||
#define MAX77620_REG_CNFGBBC 0x04
|
||||
#define MAX77620_CNFGBBC_ENABLE BIT(0)
|
||||
|
@ -64,6 +72,7 @@
|
|||
#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
|
||||
#define MAX77620_REG_IRQTOP 0x05
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_IRQ_TOP_ONOFF_MASK BIT(1)
|
||||
#define MAX77620_IRQ_TOP_32K_MASK BIT(2)
|
||||
#define MAX77620_IRQ_TOP_RTC_MASK BIT(3)
|
||||
|
@ -73,28 +82,53 @@
|
|||
#define MAX77620_IRQ_TOP_GLBL_MASK BIT(7)
|
||||
|
||||
#define MAX77620_REG_INTLBT 0x06
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_IRQ_GLBLM_MASK BIT(0)
|
||||
#define MAX77620_IRQ_TJALRM2_MASK BIT(1)
|
||||
#define MAX77620_IRQ_TJALRM1_MASK BIT(2)
|
||||
#define MAX77620_IRQ_LBM_MASK BIT(3)
|
||||
|
||||
#define MAX77620_REG_IRQSD 0x07
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_NVERC 0x0C
|
||||
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_GLBLM_MASK BIT(0)
|
||||
|
||||
#define MAX77620_REG_IRQMASKSD 0x0F
|
||||
#define MAX77620_IRQSD_PFI_SD3 BIT(4)
|
||||
#define MAX77620_IRQSD_PFI_SD2 BIT(5)
|
||||
#define MAX77620_IRQSD_PFI_SD1 BIT(6)
|
||||
#define MAX77620_IRQSD_PFI_SD0 BIT(7)
|
||||
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 // LDO number that irq occurred.
|
||||
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09 // LDO number that irq occurred. Only bit0: LDO8 is valid.
|
||||
#define MAX77620_REG_IRQ_MSK_L8 0x11
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A // Edge detection interrupt.
|
||||
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_ONOFFIRQM 0x12
|
||||
#define MAX77620_ONOFFIRQ_MRWRN BIT(0)
|
||||
#define MAX77620_ONOFFIRQ_EN0_1SEC BIT(1)
|
||||
#define MAX77620_ONOFFIRQ_EN0_F BIT(2)
|
||||
#define MAX77620_ONOFFIRQ_EN0_R BIT(3)
|
||||
#define MAX77620_ONOFFIRQ_LID_F BIT(4)
|
||||
#define MAX77620_ONOFFIRQ_LID_R BIT(5)
|
||||
#define MAX77620_ONOFFIRQ_ACOK_F BIT(6)
|
||||
#define MAX77620_ONOFFIRQ_ACOK_R BIT(7)
|
||||
|
||||
#define MAX77620_REG_NVERC 0x0C // Shutdown reason (non-volatile).
|
||||
#define MAX77620_NVERC_SHDN BIT(0)
|
||||
#define MAX77620_NVERC_WTCHDG BIT(1)
|
||||
#define MAX77620_NVERC_HDRST BIT(2)
|
||||
#define MAX77620_NVERC_TOVLD BIT(3)
|
||||
#define MAX77620_NVERC_MBLSD BIT(4)
|
||||
#define MAX77620_NVERC_MBO BIT(5)
|
||||
#define MAX77620_NVERC_MBU BIT(6)
|
||||
#define MAX77620_NVERC_RSTIN BIT(7)
|
||||
|
||||
#define MAX77620_REG_STATLBT 0x13
|
||||
#define MAX77620_REG_STATSD 0x14
|
||||
|
||||
#define MAX77620_REG_ONOFFSTAT 0x15
|
||||
#define MAX77620_ONOFFSTAT_LID BIT(0)
|
||||
#define MAX77620_ONOFFSTAT_ACOK BIT(1)
|
||||
#define MAX77620_ONOFFSTAT_EN0 BIT(2)
|
||||
|
||||
/* SD and LDO Registers */
|
||||
#define MAX77620_REG_SD0 0x16
|
||||
|
@ -102,18 +136,42 @@
|
|||
#define MAX77620_REG_SD2 0x18
|
||||
#define MAX77620_REG_SD3 0x19
|
||||
#define MAX77620_REG_SD4 0x1A
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x3F
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
#define MAX77620_REG_DVSSD0 0x1B
|
||||
#define MAX77620_REG_DVSSD1 0x1C
|
||||
#define MAX77620_REG_SD0_CFG 0x1D // SD CNFG1.
|
||||
#define MAX77620_REG_SD1_CFG 0x1E // SD CNFG1.
|
||||
#define MAX77620_REG_SD2_CFG 0x1F // SD CNFG1.
|
||||
#define MAX77620_REG_SD3_CFG 0x20 // SD CNFG1.
|
||||
#define MAX77620_REG_SD4_CFG 0x21 // SD CNFG1.
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x7F // Max is 0x40.
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F // Max is 0x4C.
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
|
||||
#define MAX77620_REG_SD0_CFG 0x1D
|
||||
#define MAX77620_REG_SD1_CFG 0x1E
|
||||
#define MAX77620_REG_SD2_CFG 0x1F
|
||||
#define MAX77620_REG_SD3_CFG 0x20
|
||||
#define MAX77620_REG_SD4_CFG 0x21
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
|
||||
#define MAX77620_SD_CFG1_MPOK_MASK BIT(1)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
|
||||
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_SD_CNF2_RSVD BIT(0)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
|
||||
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
#define MAX77620_REG_LDO1_CFG 0x25
|
||||
|
@ -132,26 +190,36 @@
|
|||
#define MAX77620_REG_LDO7_CFG2 0x32
|
||||
#define MAX77620_REG_LDO8_CFG 0x33
|
||||
#define MAX77620_REG_LDO8_CFG2 0x34
|
||||
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW 0
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
|
||||
#define MAX20024_LDO_CFG2_MPOK_MASK BIT(2)
|
||||
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
|
||||
/*! LDO CFG */
|
||||
#define MAX77620_LDO_POWER_MODE_SHIFT 6
|
||||
#define MAX77620_LDO_POWER_MODE_MASK (3 << MAX77620_LDO_POWER_MODE_SHIFT)
|
||||
#define MAX77620_POWER_MODE_NORMAL 3
|
||||
#define MAX77620_POWER_MODE_LPM 2
|
||||
#define MAX77620_POWER_MODE_GLPM 1
|
||||
#define MAX77620_POWER_MODE_DISABLE 0
|
||||
/*! LDO CFG2 */
|
||||
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST (0 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_MPOK_MASK BIT(2)
|
||||
#define MAX77620_LDO_CFG2_POK_MASK BIT(3)
|
||||
#define MAX77620_LDO_CFG2_COMP_SHIFT 4
|
||||
#define MAX77620_LDO_CFG2_COMP_MASK (3 << MAX77620_LDO_COMP_SHIFT)
|
||||
#define MAX77620_LDO_CFG2_COMP_SLOW 3
|
||||
#define MAX77620_LDO_CFG2_COMP_MID_SLOW 2
|
||||
#define MAX77620_LDO_CFG2_COMP_MID_FAST 1
|
||||
#define MAX77620_LDO_CFG2_COMP_FAST 0
|
||||
#define MAX77620_LDO_CFG2_ALPM_EN_MASK BIT(6)
|
||||
#define MAX77620_LDO_CFG2_OVCLMP_MASK BIT(7)
|
||||
|
||||
#define MAX77620_REG_LDO_CFG3 0x35
|
||||
#define MAX77620_LDO_BIAS_EN BIT(0)
|
||||
#define MAX77620_TRACK4_SHIFT 5
|
||||
#define MAX77620_TRACK4_MASK (1 << MAX77620_TRACK4_SHIFT)
|
||||
|
||||
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
|
||||
|
||||
#define MAX77620_REG_GPIO0 0x36
|
||||
#define MAX77620_REG_GPIO1 0x37
|
||||
#define MAX77620_REG_GPIO2 0x38
|
||||
|
@ -160,9 +228,6 @@
|
|||
#define MAX77620_REG_GPIO5 0x3B
|
||||
#define MAX77620_REG_GPIO6 0x3C
|
||||
#define MAX77620_REG_GPIO7 0x3D
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F
|
||||
#define MAX77620_REG_AME_GPIO 0x40
|
||||
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN (0 << 0)
|
||||
|
@ -181,6 +246,13 @@
|
|||
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
|
||||
#define MAX77620_GPIO_OUTPUT_DISABLE 0
|
||||
#define MAX77620_GPIO_OUTPUT_ENABLE 1
|
||||
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E // Gpio Pullup resistor enable.
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F // Gpio Pulldown resistor enable.
|
||||
|
||||
#define MAX77620_REG_AME_GPIO 0x40 // Gpio pinmuxing. Clear bits are Standard GPIO.
|
||||
|
||||
#define MAX77620_REG_ONOFFCNFG1 0x41
|
||||
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
|
||||
|
@ -188,19 +260,30 @@
|
|||
#define MAX77620_ONOFFCNFG1_SLPEN BIT(2)
|
||||
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
|
||||
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
|
||||
#define MAX77620_ONOFFCNFG1_RSVD BIT(6)
|
||||
#define MAX77620_ONOFFCNFG1_SFT_RST BIT(7)
|
||||
|
||||
#define MAX77620_REG_ONOFFCNFG2 0x42
|
||||
#define MAX77620_ONOFFCNFG2_WK_EN0 BIT(0)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM2 BIT(1)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM1 BIT(2)
|
||||
#define MAX77620_ONOFFCNFG2_WK_MBATT BIT(3) // MBATT event generates a wakeup signal. use it in android/l4t?
|
||||
#define MAX77620_ONOFFCNFG2_WK_ACOK BIT(4)
|
||||
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK BIT(5)
|
||||
#define MAX77620_ONOFFCNFG2_WD_RST_WK BIT(6)
|
||||
#define MAX77620_ONOFFCNFG2_SFT_RST_WK BIT(7)
|
||||
|
||||
/* FPS Registers */
|
||||
#define MAX77620_REG_FPS_CFG0 0x43
|
||||
#define MAX77620_REG_FPS_CFG1 0x44
|
||||
#define MAX77620_REG_FPS_CFG2 0x45
|
||||
#define MAX77620_REG_FPS_CFG0 0x43 // FPS0.
|
||||
#define MAX77620_REG_FPS_CFG1 0x44 // FPS1.
|
||||
#define MAX77620_REG_FPS_CFG2 0x45 // FPS2.
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
|
||||
#define MAX77620_REG_FPS_LDO0 0x46
|
||||
#define MAX77620_REG_FPS_LDO1 0x47
|
||||
#define MAX77620_REG_FPS_LDO2 0x48
|
||||
|
@ -215,77 +298,39 @@
|
|||
#define MAX77620_REG_FPS_SD2 0x51
|
||||
#define MAX77620_REG_FPS_SD3 0x52
|
||||
#define MAX77620_REG_FPS_SD4 0x53
|
||||
#define MAX77620_REG_FPS_NONE 0
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
|
||||
/* Minimum and maximum FPS period time (in microseconds) are
|
||||
* different for MAX77620 and Max20024.
|
||||
*/
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX20024_FPS_PERIOD_MIN_US 20
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
#define MAX20024_FPS_PERIOD_MAX_US 5120
|
||||
|
||||
#define MAX77620_REG_FPS_GPIO1 0x54
|
||||
#define MAX77620_REG_FPS_GPIO2 0x55
|
||||
#define MAX77620_REG_FPS_GPIO3 0x56
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
|
||||
#define MAX77620_REG_FPS_RSO 0x57
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
|
||||
#define MAX77620_REG_CID0 0x58
|
||||
#define MAX77620_REG_CID1 0x59
|
||||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
|
||||
/* CNCG2SD */
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
|
||||
#define MAX77620_REG_CID4 0x5C // OTP version.
|
||||
#define MAX77620_REG_CID5 0x5D // ES version.
|
||||
#define MAX77620_CID_DIDO_MASK 0xF
|
||||
#define MAX77620_CID_DIDO_SHIFT 0
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
|
||||
/* Device Identification Metal */
|
||||
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
|
||||
/* Device Indentification OTP */
|
||||
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
|
||||
|
||||
/* SD CNFG1 */
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
|
||||
#define MAX20024_SD_CFG1_MPOK_MASK BIT(1)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 BIT(0)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 BIT(1)
|
||||
|
@ -332,9 +377,4 @@ enum max77620_fps_src {
|
|||
MAX77620_FPS_SRC_DEF,
|
||||
};
|
||||
|
||||
enum max77620_chip_id {
|
||||
MAX77620,
|
||||
MAX20024,
|
||||
};
|
||||
|
||||
#endif /* _MFD_MAX77620_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,163 +17,334 @@
|
|||
|
||||
#include <power/max7762x.h>
|
||||
#include <power/max77620.h>
|
||||
#include <power/max77812.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
#define REGULATOR_SD 0
|
||||
#define REGULATOR_SD 0
|
||||
#define REGULATOR_LDO 1
|
||||
#define REGULATOR_BC0 2
|
||||
#define REGULATOR_BC1 3
|
||||
|
||||
typedef struct _max77620_regulator_t
|
||||
typedef struct _max77620_fps_t
|
||||
{
|
||||
u8 type;
|
||||
const char *name;
|
||||
u8 reg_sd;
|
||||
|
||||
u32 mv_step;
|
||||
u32 mv_min;
|
||||
u32 mv_default;
|
||||
u32 mv_max;
|
||||
|
||||
u8 volt_addr;
|
||||
u8 cfg_addr;
|
||||
|
||||
u8 volt_mask;
|
||||
u8 enable_mask;
|
||||
u8 enable_shift;
|
||||
u8 status_mask;
|
||||
|
||||
u8 fps_addr;
|
||||
u8 fps_src;
|
||||
u8 pd_period;
|
||||
u8 pu_period;
|
||||
} max77620_fps_t;
|
||||
|
||||
typedef struct _max77621_ctrl_t
|
||||
{
|
||||
u8 ctrl1_por;
|
||||
u8 ctrl1_hos;
|
||||
u8 ctrl2_por;
|
||||
u8 ctrl2_hos;
|
||||
} max77621_ctrl_t;
|
||||
|
||||
typedef struct _max77812_ctrl_t
|
||||
{
|
||||
u8 mask;
|
||||
u8 shift;
|
||||
u8 rsvd0;
|
||||
u8 rsvd1;
|
||||
} max77812_en_t;
|
||||
|
||||
typedef struct _max77620_regulator_t
|
||||
{
|
||||
const char *name;
|
||||
|
||||
u32 uv_step;
|
||||
u32 uv_min;
|
||||
u32 uv_default;
|
||||
u32 uv_max;
|
||||
|
||||
u8 type;
|
||||
u8 volt_addr;
|
||||
u8 cfg_addr;
|
||||
u8 volt_mask;
|
||||
|
||||
union {
|
||||
max77620_fps_t fps;
|
||||
max77621_ctrl_t ctrl;
|
||||
max77812_en_t enable;
|
||||
};
|
||||
} max77620_regulator_t;
|
||||
|
||||
static const max77620_regulator_t _pmic_regulators[] = {
|
||||
{ REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x80, MAX77620_REG_FPS_SD0, 1, 7, 1 },
|
||||
{ REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x40, MAX77620_REG_FPS_SD1, 0, 1, 5 },
|
||||
{ REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x20, MAX77620_REG_FPS_SD2, 1, 5, 2 },
|
||||
{ REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x10, MAX77620_REG_FPS_SD3, 0, 3, 3 },
|
||||
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO0, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO1, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO2, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO3, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 1000000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO4, 0, 7, 1 },
|
||||
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 },
|
||||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 2800000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
||||
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
|
||||
{ "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
|
||||
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
|
||||
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
|
||||
{ "ldo1", 25000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO1, 3, 7, 0 }} },
|
||||
{ "ldo2", 50000, 800000, 1800000, 3300000, REGULATOR_LDO, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO2, 3, 7, 0 }} },
|
||||
{ "ldo3", 50000, 800000, 3100000, 3100000, REGULATOR_LDO, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO3, 3, 7, 0 }} },
|
||||
{ "ldo4", 12500, 800000, 850000, 1000000, REGULATOR_LDO, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO4, 0, 7, 1 }} },
|
||||
{ "ldo5", 50000, 800000, 1800000, 1800000, REGULATOR_LDO, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO5, 3, 7, 0 }} },
|
||||
{ "ldo6", 50000, 800000, 2900000, 2900000, REGULATOR_LDO, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO6, 3, 7, 0 }} },
|
||||
{ "ldo7", 50000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO7, 1, 4, 3 }} },
|
||||
{ "ldo8", 50000, 800000, 1050000, 2800000, REGULATOR_LDO, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO8, 3, 7, 0 }} },
|
||||
|
||||
{ "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77812_CPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M4_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M4_MASK, MAX77812_EN_CTRL_EN_M4_SHIFT, 0, 0 }} },
|
||||
{ "max77812_RAM", 5000, 250000, 600000, 650000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration.
|
||||
//{ "max77812_GPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M1_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M1_MASK, MAX77812_EN_CTRL_EN_M1_SHIFT, 0, 0 }} },
|
||||
};
|
||||
|
||||
static void _max77620_set_reg(u8 reg, u8 val)
|
||||
static u8 _max77812_get_address()
|
||||
{
|
||||
static u8 max77812_i2c_addr = 0;
|
||||
|
||||
if (max77812_i2c_addr)
|
||||
return max77812_i2c_addr;
|
||||
|
||||
max77812_i2c_addr =
|
||||
!(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
|
||||
|
||||
return max77812_i2c_addr;
|
||||
}
|
||||
|
||||
static u8 _max7762x_get_i2c_address(u32 id)
|
||||
{
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
// Choose the correct i2c address.
|
||||
switch (reg->type)
|
||||
{
|
||||
case REGULATOR_SD:
|
||||
case REGULATOR_LDO:
|
||||
return MAX77620_I2C_ADDR;
|
||||
case REGULATOR_BC0:
|
||||
return (id == REGULATOR_CPU0 ? MAX77621_CPU_I2C_ADDR : MAX77621_GPU_I2C_ADDR);
|
||||
case REGULATOR_BC1:
|
||||
{
|
||||
u8 reg_addr = _max77812_get_address();
|
||||
if (id == REGULATOR_RAM0 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
|
||||
reg_addr = 0;
|
||||
return reg_addr;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void _max7762x_set_reg(u8 addr, u8 reg, u8 val)
|
||||
{
|
||||
u32 retries = 100;
|
||||
while (retries)
|
||||
{
|
||||
if (i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val))
|
||||
if (i2c_send_byte(I2C_5, addr, reg, val))
|
||||
break;
|
||||
usleep(100);
|
||||
|
||||
usleep(50);
|
||||
retries--;
|
||||
}
|
||||
}
|
||||
|
||||
int max77620_regulator_get_status(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
if (id > REGULATOR_LDO8)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
// SD power OK status.
|
||||
if (reg->type == REGULATOR_SD)
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & 8) ? 1 : 0;
|
||||
{
|
||||
u8 mask = 1u << (7 - id);
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & mask) ? 0 : 1;
|
||||
}
|
||||
|
||||
// LDO power OK status.
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & MAX77620_LDO_CFG2_POK_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
int max77620_regulator_config_fps(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
if (id > REGULATOR_LDO8)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
_max77620_set_reg(reg->fps_addr,
|
||||
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
||||
// Set FPS configuration.
|
||||
_max7762x_set_reg(MAX77620_I2C_ADDR,
|
||||
reg->fps.fps_addr,
|
||||
(reg->fps.fps_src << MAX77620_FPS_SRC_SHIFT) |
|
||||
(reg->fps.pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) |
|
||||
(reg->fps.pd_period << MAX77620_FPS_PD_PERIOD_SHIFT));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv)
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 uv)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
if (uv < reg->uv_min || uv > reg->uv_max)
|
||||
return 0;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
// Calculate voltage multiplier.
|
||||
u32 mult = (uv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
|
||||
u8 val = i2c_recv_byte(I2C_5, addr, reg->volt_addr);
|
||||
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
_max77620_set_reg(reg->volt_addr, val);
|
||||
|
||||
// Set voltage.
|
||||
_max7762x_set_reg(addr, reg->volt_addr, val);
|
||||
|
||||
// If max77621 set DVS voltage also.
|
||||
if (reg->type == REGULATOR_BC0)
|
||||
_max7762x_set_reg(addr, reg->cfg_addr, MAX77621_VOUT_ENABLE_MASK | val);
|
||||
|
||||
// Wait for ramp up/down delay.
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_enable(u32 id, int enable)
|
||||
int max7762x_regulator_enable(u32 id, bool enable)
|
||||
{
|
||||
u8 reg_addr;
|
||||
u8 enable_val;
|
||||
u8 enable_mask;
|
||||
u8 enable_shift;
|
||||
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);
|
||||
// Choose the correct i2c and register addresses and mask/shift for each type.
|
||||
switch (reg->type)
|
||||
{
|
||||
case REGULATOR_SD:
|
||||
reg_addr = reg->cfg_addr;
|
||||
enable_val = MAX77620_POWER_MODE_NORMAL;
|
||||
enable_mask = MAX77620_SD_POWER_MODE_MASK;
|
||||
enable_shift = MAX77620_SD_POWER_MODE_SHIFT;
|
||||
break;
|
||||
case REGULATOR_LDO:
|
||||
reg_addr = reg->volt_addr;
|
||||
enable_val = MAX77620_POWER_MODE_NORMAL;
|
||||
enable_mask = MAX77620_LDO_POWER_MODE_MASK;
|
||||
enable_shift = MAX77620_LDO_POWER_MODE_SHIFT;
|
||||
break;
|
||||
case REGULATOR_BC0:
|
||||
reg_addr = reg->volt_addr;
|
||||
enable_val = MAX77621_VOUT_ENABLE;
|
||||
enable_mask = MAX77621_DVC_DVS_ENABLE_MASK;
|
||||
enable_shift = MAX77621_DVC_DVS_ENABLE_SHIFT;
|
||||
break;
|
||||
case REGULATOR_BC1:
|
||||
reg_addr = reg->cfg_addr;
|
||||
enable_val = MAX77812_EN_CTRL_ENABLE;
|
||||
enable_mask = reg->enable.mask;
|
||||
enable_shift = reg->enable.shift;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
// Read and enable/disable.
|
||||
u8 val = i2c_recv_byte(I2C_5, addr, reg_addr);
|
||||
val &= ~enable_mask;
|
||||
|
||||
if (enable)
|
||||
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
||||
else
|
||||
val &= ~reg->enable_mask;
|
||||
_max77620_set_reg(addr, val);
|
||||
val |= (enable_val << enable_shift);
|
||||
|
||||
// Set enable.
|
||||
_max7762x_set_reg(addr, reg_addr, val);
|
||||
|
||||
// Wait for enable/disable ramp delay.
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// LDO only.
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
||||
void max77620_config_gpio(u32 gpio_id, bool enable)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
if (gpio_id > 7)
|
||||
return;
|
||||
|
||||
// Configure as standard GPIO.
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, val & ~BIT(gpio_id));
|
||||
|
||||
// Set GPIO configuration.
|
||||
if (enable)
|
||||
val = MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DIR_OUTPUT | MAX77620_CNFG_GPIO_DRV_PUSHPULL;
|
||||
else
|
||||
val = MAX77620_CNFG_GPIO_DIR_INPUT | MAX77620_CNFG_GPIO_DRV_OPENDRAIN;
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO0 + gpio_id, val);
|
||||
}
|
||||
|
||||
void max77621_config_default(u32 id, bool por)
|
||||
{
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
return 0;
|
||||
if (reg->type != REGULATOR_BC0)
|
||||
return;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
_max77620_set_reg(reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
return 1;
|
||||
if (por)
|
||||
{
|
||||
// Set voltage and disable power before changing the inductor.
|
||||
max7762x_regulator_set_voltage(id, 1000000);
|
||||
max7762x_regulator_enable(id, false);
|
||||
|
||||
// Configure to default.
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_por);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_por);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_hos);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_hos);
|
||||
}
|
||||
}
|
||||
|
||||
void max77620_config_default()
|
||||
{
|
||||
for (u32 i = 1; i <= REGULATOR_MAX; i++)
|
||||
// Check if Erista OTP.
|
||||
if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4) != 0x35)
|
||||
return;
|
||||
|
||||
// Set default voltages and enable regulators.
|
||||
for (u32 i = 1; i <= REGULATOR_LDO8; i++)
|
||||
{
|
||||
i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
|
||||
max77620_regulator_config_fps(i);
|
||||
max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
|
||||
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
|
||||
max77620_regulator_enable(i, 1);
|
||||
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
|
||||
if (_pmic_regulators[i].fps.fps_src != MAX77620_FPS_SRC_NONE)
|
||||
max7762x_regulator_enable(i, true);
|
||||
}
|
||||
_max77620_set_reg(MAX77620_REG_SD_CFG2, 4);
|
||||
|
||||
// Enable SD0 output voltage sense and disable for SD1. Additionally disable the reserved bit.
|
||||
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0);
|
||||
}
|
||||
|
||||
// Stock HOS: disabled.
|
||||
void max77620_low_battery_monitor_config(bool enable)
|
||||
{
|
||||
_max77620_set_reg(MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
|
||||
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
|
||||
_max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN |
|
||||
(enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
|
||||
MAX77620_CNFGGLBL1_LBHYST_200 |
|
||||
MAX77620_CNFGGLBL1_LBDAC_2800);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -20,6 +20,14 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
/*
|
||||
* SDx actual min is 625 mV. Multipliers 0/1 reserved.
|
||||
* SD0 max is 1400 mV
|
||||
* SD1 max is 1550 mV
|
||||
* SD2 max is 3787.5 mV
|
||||
* SD3 max is 3787.5 mV
|
||||
*/
|
||||
|
||||
/*
|
||||
* Switch Power domains (max77620):
|
||||
* Name | Usage | uV step | uV min | uV default | uV max | Init
|
||||
|
@ -32,23 +40,44 @@
|
|||
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | 0.85V (AO, pcv)
|
||||
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv)
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
|
||||
*/
|
||||
|
||||
|
||||
// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
|
||||
|
||||
/*
|
||||
* OTP: T210 - T210B01:
|
||||
* SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
|
||||
* SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
|
||||
* SD2: 1.35V 1.35V
|
||||
* SD3: 1.8V 1.8V
|
||||
* All powered off?
|
||||
* LDO0: -- -- - Display
|
||||
* LDO1: 1.05V 1.05V
|
||||
* LDO2: -- -- - SD
|
||||
* LDO3: 3.1V 3.1V - GC ASIC
|
||||
* LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
|
||||
* LDO5: 3.1V 3.1V
|
||||
* LDO6: 2.8V 2.9V - Touch.
|
||||
* LDO7: 1.05V 1.0V
|
||||
* LDO8: 1.05V 1.0V
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
|
||||
* MAX77620_REG_GPIOx: 0x9 sets output and enable
|
||||
*/
|
||||
|
||||
/*! MAX77620 partitions. */
|
||||
#define REGULATOR_SD0 0
|
||||
#define REGULATOR_SD1 1
|
||||
#define REGULATOR_SD2 2
|
||||
#define REGULATOR_SD3 3
|
||||
#define REGULATOR_SD0 0
|
||||
#define REGULATOR_SD1 1
|
||||
#define REGULATOR_SD2 2
|
||||
#define REGULATOR_SD3 3
|
||||
#define REGULATOR_LDO0 4
|
||||
#define REGULATOR_LDO1 5
|
||||
#define REGULATOR_LDO2 6
|
||||
|
@ -58,26 +87,40 @@
|
|||
#define REGULATOR_LDO6 10
|
||||
#define REGULATOR_LDO7 11
|
||||
#define REGULATOR_LDO8 12
|
||||
#define REGULATOR_MAX 12
|
||||
#define REGULATOR_CPU0 13 // T210 CPU.
|
||||
#define REGULATOR_GPU0 14 // T210 CPU.
|
||||
#define REGULATOR_CPU1 15 // T210B01 CPU.
|
||||
#define REGULATOR_RAM0 16 // T210B01 RAM for PHASE211.
|
||||
//#define REGULATOR_GPU1 17 // T210B01 CPU.
|
||||
#define REGULATOR_MAX REGULATOR_RAM0
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
|
||||
#define MAX77621_VOUT_REG 0
|
||||
#define MAX77621_VOUT_DVS_REG 1
|
||||
#define MAX77621_CONTROL1_REG 2
|
||||
#define MAX77621_CONTROL2_REG 3
|
||||
|
||||
/* MAX77621_VOUT */
|
||||
#define MAX77621_VOUT_ENABLE BIT(7)
|
||||
#define MAX77621_VOUT_MASK 0x7F
|
||||
#define MAX77621_VOUT_0_95V 0x37
|
||||
#define MAX77621_VOUT_1_09V 0x4F
|
||||
#define MAX77621_REG_VOUT 0x00
|
||||
#define MAX77621_REG_VOUT_DVS 0x01
|
||||
#define MAX77621_REG_CONTROL1 0x02
|
||||
#define MAX77621_REG_CONTROL2 0x03
|
||||
#define MAX77621_REG_CHIPID1 0x04
|
||||
#define MAX77621_REG_CHIPID2 0x05
|
||||
|
||||
/* MAX77621_VOUT_DVC_DVS */
|
||||
#define MAX77621_DVS_VOUT_MASK 0x7F
|
||||
#define MAX77621_DVC_DVS_VOLT_MASK 0x7F
|
||||
#define MAX77621_DVC_DVS_ENABLE_SHIFT 7
|
||||
#define MAX77621_DVC_DVS_ENABLE_MASK (1 << MAX77621_DVC_DVS_ENABLE_SHIFT)
|
||||
|
||||
/* MAX77621_VOUT */
|
||||
#define MAX77621_VOUT_DISABLE 0
|
||||
#define MAX77621_VOUT_ENABLE 1
|
||||
#define MAX77621_VOUT_ENABLE_MASK (MAX77621_VOUT_ENABLE << MAX77621_DVC_DVS_ENABLE_SHIFT)
|
||||
|
||||
/* MAX77621_CONTROL1 */
|
||||
#define MAX77621_RAMP_12mV_PER_US 0x0
|
||||
#define MAX77621_RAMP_25mV_PER_US 0x1
|
||||
#define MAX77621_RAMP_50mV_PER_US 0x2
|
||||
#define MAX77621_RAMP_200mV_PER_US 0x3
|
||||
#define MAX77621_RAMP_MASK 0x3
|
||||
|
||||
#define MAX77621_FREQSHIFT_9PER BIT(2)
|
||||
#define MAX77621_BIAS_ENABLE BIT(3)
|
||||
#define MAX77621_AD_ENABLE BIT(4)
|
||||
|
@ -85,34 +128,48 @@
|
|||
#define MAX77621_FPWM_EN_M BIT(6)
|
||||
#define MAX77621_SNS_ENABLE BIT(7)
|
||||
|
||||
#define MAX77621_RAMP_12mV_PER_US 0x0
|
||||
#define MAX77621_RAMP_25mV_PER_US 0x1
|
||||
#define MAX77621_RAMP_50mV_PER_US 0x2
|
||||
#define MAX77621_RAMP_200mV_PER_US 0x3
|
||||
#define MAX77621_RAMP_MASK 0x3
|
||||
|
||||
/* MAX77621_CONTROL2 */
|
||||
#define MAX77621_FT_ENABLE BIT(4)
|
||||
#define MAX77621_DISCH_ENBABLE BIT(5)
|
||||
#define MAX77621_INDUCTOR_MIN_30_PER 0
|
||||
#define MAX77621_INDUCTOR_NOMINAL 1
|
||||
#define MAX77621_INDUCTOR_PLUS_30_PER 2
|
||||
#define MAX77621_INDUCTOR_PLUS_60_PER 3
|
||||
#define MAX77621_INDUCTOR_MASK 3
|
||||
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US (0 << 2)
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US (1u << 2)
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE (3u << 2)
|
||||
#define MAX77621_CKKADV_TRIP_MASK (3u << 2)
|
||||
|
||||
#define MAX77621_FT_ENABLE BIT(4)
|
||||
#define MAX77621_DISCH_ENABLE BIT(5)
|
||||
#define MAX77621_WDTMR_ENABLE BIT(6)
|
||||
#define MAX77621_T_JUNCTION_120 BIT(7)
|
||||
#define MAX77621_T_JUNCTION_120 BIT(7)
|
||||
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE 0xC
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US 0x4
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
|
||||
#define MAX77621_CPU_CTRL1_POR_DEFAULT (MAX77621_RAMP_50mV_PER_US)
|
||||
#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \
|
||||
MAX77621_NFSR_ENABLE | \
|
||||
MAX77621_SNS_ENABLE | \
|
||||
MAX77621_RAMP_12mV_PER_US)
|
||||
#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_FT_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_DISABLE | \
|
||||
MAX77621_INDUCTOR_NOMINAL)
|
||||
#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_WDTMR_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_75mV_PER_US | \
|
||||
MAX77621_INDUCTOR_NOMINAL)
|
||||
|
||||
#define MAX77621_INDUCTOR_MIN_30_PER 0x0
|
||||
#define MAX77621_INDUCTOR_NOMINAL 0x1
|
||||
#define MAX77621_INDUCTOR_PLUS_30_PER 0x2
|
||||
#define MAX77621_INDUCTOR_PLUS_60_PER 0x3
|
||||
#define MAX77621_CTRL_HOS_CFG 0
|
||||
#define MAX77621_CTRL_POR_CFG 1
|
||||
|
||||
int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max77620_regulator_enable(u32 id, int enable);
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
|
||||
int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 uv);
|
||||
int max7762x_regulator_enable(u32 id, bool enable);
|
||||
void max77620_config_gpio(u32 id, bool enable);
|
||||
void max77620_config_default();
|
||||
void max77620_low_battery_monitor_config(bool enable);
|
||||
|
||||
void max77621_config_default(u32 id, bool por);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#ifndef _MAX77812_H_
|
||||
#define _MAX77812_H_
|
||||
|
||||
#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31
|
||||
#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33
|
||||
#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31 // High power GPU. 2 Outputs: 3-phase M1 + 1-phase M4.
|
||||
#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33 // Low power GPU. 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4.
|
||||
|
||||
#define MAX77812_REG_RSET 0x00
|
||||
#define MAX77812_REG_INT_SRC 0x01
|
||||
|
@ -27,7 +27,15 @@
|
|||
#define MAX77812_REG_TOPSYS_INT_M 0x04
|
||||
#define MAX77812_REG_TOPSYS_STAT 0x05
|
||||
#define MAX77812_REG_EN_CTRL 0x06
|
||||
#define MAX77812_EN_CTRL_EN_M4 BIT(6)
|
||||
#define MAX77812_EN_CTRL_ENABLE 1
|
||||
#define MAX77812_EN_CTRL_EN_M1_SHIFT 0
|
||||
#define MAX77812_EN_CTRL_EN_M1_MASK (1 << MAX77812_EN_CTRL_EN_M1_SHIFT)
|
||||
#define MAX77812_EN_CTRL_EN_M2_SHIFT 2
|
||||
#define MAX77812_EN_CTRL_EN_M2_MASK (1 << MAX77812_EN_CTRL_EN_M2_SHIFT)
|
||||
#define MAX77812_EN_CTRL_EN_M3_SHIFT 4
|
||||
#define MAX77812_EN_CTRL_EN_M3_MASK (1 << MAX77812_EN_CTRL_EN_M3_SHIFT)
|
||||
#define MAX77812_EN_CTRL_EN_M4_SHIFT 6
|
||||
#define MAX77812_EN_CTRL_EN_M4_MASK (1 << MAX77812_EN_CTRL_EN_M4_SHIFT)
|
||||
#define MAX77812_REG_STUP_DLY2 0x07
|
||||
#define MAX77812_REG_STUP_DLY3 0x08
|
||||
#define MAX77812_REG_STUP_DLY4 0x09
|
||||
|
@ -46,11 +54,10 @@
|
|||
#define MAX77812_REG_BUCK_INT 0x20
|
||||
#define MAX77812_REG_BUCK_INT_M 0x21
|
||||
#define MAX77812_REG_BUCK_STAT 0x22
|
||||
#define MAX77812_REG_M1_VOUT 0x23
|
||||
#define MAX77812_REG_M1_VOUT 0x23 // GPU.
|
||||
#define MAX77812_REG_M2_VOUT 0x24
|
||||
#define MAX77812_REG_M3_VOUT 0x25
|
||||
#define MAX77812_REG_M4_VOUT 0x26
|
||||
#define MAX77812_M4_VOUT_0_80V 0x6E
|
||||
#define MAX77812_REG_M3_VOUT 0x25 // DRAM on PHASE211.
|
||||
#define MAX77812_REG_M4_VOUT 0x26 // CPU.
|
||||
#define MAX77812_REG_M1_VOUT_D 0x27
|
||||
#define MAX77812_REG_M2_VOUT_D 0x28
|
||||
#define MAX77812_REG_M3_VOUT_D 0x29
|
||||
|
@ -59,20 +66,23 @@
|
|||
#define MAX77812_REG_M2_VOUT_S 0x2C
|
||||
#define MAX77812_REG_M3_VOUT_S 0x2D
|
||||
#define MAX77812_REG_M4_VOUT_S 0x2E
|
||||
#define MAX77812_REG_M1_CFG 0x2F
|
||||
#define MAX77812_REG_M2_CFG 0x30
|
||||
#define MAX77812_REG_M3_CFG 0x31
|
||||
#define MAX77812_REG_M4_CFG 0x32
|
||||
#define MAX77812_REG_GLB_CFG1 0x33
|
||||
#define MAX77812_REG_GLB_CFG2 0x34
|
||||
#define MAX77812_REG_M1_CFG 0x2F // HOS: M1_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M2_CFG 0x30 // HOS: M2_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M3_CFG 0x31 // HOS: M3_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M4_CFG 0x32 // HOS: M4_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_GLB_CFG1 0x33 // HOS: B_SD_SR/B_SS_SR - 5mV/us.
|
||||
#define MAX77812_REG_GLB_CFG2 0x34 // HOS: B_RD_SR/B_RU_SR - 5mV/us
|
||||
#define MAX77812_REG_GLB_CFG3 0x35
|
||||
#define MAX77812_REG_GLB_CFG4 0x36
|
||||
#define MAX77812_REG_GLB_CFG5 0x37
|
||||
#define MAX77812_REG_GLB_CFG6 0x38
|
||||
#define MAX77812_REG_GLB_CFG7 0x39
|
||||
#define MAX77812_REG_GLB_CFG8 0x3A
|
||||
#define MAX77812_REG_PROT_ACCESS 0xFD
|
||||
#define MAX77812_REG_MAX 0xFE
|
||||
|
||||
/*! Protected area and settings only for MAX77812_ES2_VERSION */
|
||||
#define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
|
||||
#define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
|
||||
#define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
|
||||
#define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
|
||||
#define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
|
||||
|
||||
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
|
||||
#define MAX77812_REG_UNKNOWN 0xFE
|
||||
|
||||
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
|
||||
#define MAX77812_START_SLEW_RATE_MASK 0x07
|
||||
|
@ -91,10 +101,6 @@
|
|||
#define MAX77812_ES2_VERSION 0x04
|
||||
#define MAX77812_QS_VERSION 0x05
|
||||
|
||||
#define MAX77812_VOUT_MASK 0xFF
|
||||
#define MAX77812_VOUT_N_VOLTAGE 0xFF
|
||||
#define MAX77812_VOUT_VMIN 250000
|
||||
#define MAX77812_VOUT_VMAX 1525000
|
||||
#define MAX77812_VOUT_STEP 5000
|
||||
#define MAX77812_BUCK_VOLT_MASK 0xFF
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -14,63 +14,90 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
static u8 reg_5v_dev = 0;
|
||||
static bool usb_src = false;
|
||||
|
||||
void regulator_enable_5v(u8 dev)
|
||||
void regulator_5v_enable(u8 dev)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// The power supply selection from battery or USB is automatic.
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Fan and Rail power from internal 5V regulator (battery).
|
||||
// Fan and Rail power from battery 5V regulator EN.
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
|
||||
// Fan and Rail power from USB 5V VDD.
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
|
||||
// Only Icosa has USB 5V VBUS rails.
|
||||
if (tegra_t210)
|
||||
{
|
||||
// Fan and Rail power from USB 5V VBUS EN.
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
||||
gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
}
|
||||
|
||||
// Make sure GPIO power is enabled.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
|
||||
// Override power detect for GPIO AO IO rails.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN;
|
||||
// Make sure GPIO IO power is enabled.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO;
|
||||
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
|
||||
|
||||
// Inform GPIO IO pads that we switched to 1.8V.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_GPIO;
|
||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||
|
||||
usb_src = false;
|
||||
}
|
||||
reg_5v_dev |= dev;
|
||||
}
|
||||
|
||||
void regulator_disable_5v(u8 dev)
|
||||
void regulator_5v_disable(u8 dev)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
reg_5v_dev &= ~dev;
|
||||
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Rail power from internal 5V regulator (battery).
|
||||
// Rail power from battery 5V regulator.
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
|
||||
// Rail power from USB 5V VDD.
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
// Only Icosa has USB 5V VBUS rails.
|
||||
if (tegra_t210)
|
||||
{
|
||||
// Rail power from USB 5V VBUS.
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
usb_src = false;
|
||||
|
||||
// GPIO AO IO rails.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool regulator_get_5v_dev_enabled(u8 dev)
|
||||
bool regulator_5v_get_dev_enabled(u8 dev)
|
||||
{
|
||||
return (reg_5v_dev & dev);
|
||||
}
|
||||
|
||||
void regulator_5v_usb_src_enable(bool enable)
|
||||
{
|
||||
// Only for Icosa.
|
||||
if (hw_get_chip_id() != GP_HIDREV_MAJOR_T210)
|
||||
return;
|
||||
|
||||
if (enable && !usb_src)
|
||||
{
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
|
||||
usb_src = true;
|
||||
}
|
||||
else if (!enable && usb_src)
|
||||
{
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
usb_src = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@ enum
|
|||
REGULATOR_5V_ALL = 0xFF
|
||||
};
|
||||
|
||||
void regulator_enable_5v(u8 dev);
|
||||
void regulator_disable_5v(u8 dev);
|
||||
bool regulator_get_5v_dev_enabled(u8 dev);
|
||||
void regulator_5v_enable(u8 dev);
|
||||
void regulator_5v_disable(u8 dev);
|
||||
bool regulator_5v_get_dev_enabled(u8 dev);
|
||||
void regulator_5v_usb_src_enable(bool enable);
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2019 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -19,7 +19,16 @@
|
|||
|
||||
#include <rtc/max77620-rtc.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
int epoch_offset = 0;
|
||||
|
||||
void max77620_rtc_prep_read()
|
||||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
||||
}
|
||||
|
||||
void max77620_rtc_get_time(rtc_time_t *time)
|
||||
{
|
||||
|
@ -35,7 +44,7 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||
// Get time.
|
||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
time->hour = hour & 0x1F;
|
||||
|
||||
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
|
||||
|
@ -53,7 +62,7 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||
}
|
||||
|
||||
// Get date.
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
||||
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
||||
}
|
||||
|
@ -64,6 +73,7 @@ void max77620_rtc_stop_alarm()
|
|||
|
||||
// Update RTC regs from RTC clock.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
||||
msleep(16);
|
||||
|
||||
// Stop alarm for both ALARM1 and ALARM2. Horizon uses ALARM2.
|
||||
for (int i = 0; i < (MAX77620_RTC_NR_TIME_REGS * 2); i++)
|
||||
|
@ -82,9 +92,9 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
|||
u32 tmp, edays, year, month, day;
|
||||
|
||||
// Set time.
|
||||
time->sec = epoch % 60;
|
||||
time->sec = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->min = epoch % 60;
|
||||
time->min = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->hour = epoch % 24;
|
||||
epoch /= 24;
|
||||
|
@ -99,14 +109,14 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
|||
day = edays - month * 30 - month * 601 / 1000;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 14)
|
||||
if (month < 14)
|
||||
{
|
||||
year -= 4716;
|
||||
month--;
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 4715;
|
||||
year -= 4715;
|
||||
month -= 13;
|
||||
}
|
||||
|
||||
|
@ -129,13 +139,13 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
|||
month = time->month;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
if (month < 3)
|
||||
{
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
|
@ -145,3 +155,60 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
|||
|
||||
return epoch;
|
||||
}
|
||||
|
||||
void max77620_rtc_get_time_adjusted(rtc_time_t *time)
|
||||
{
|
||||
max77620_rtc_get_time(time);
|
||||
if (epoch_offset)
|
||||
{
|
||||
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
|
||||
max77620_rtc_epoch_to_date(epoch, time);
|
||||
}
|
||||
}
|
||||
|
||||
void max77620_rtc_set_epoch_offset(int offset)
|
||||
{
|
||||
epoch_offset = offset;
|
||||
}
|
||||
|
||||
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
|
||||
{
|
||||
max77620_rtc_stop_alarm();
|
||||
|
||||
// Set reboot reason.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG, rr->enc.val1);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG, rr->enc.val2);
|
||||
|
||||
// Set reboot reason magic.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
|
||||
|
||||
// Update RTC clock from RTC regs.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
|
||||
msleep(16);
|
||||
}
|
||||
|
||||
bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr)
|
||||
{
|
||||
u8 magic[2];
|
||||
|
||||
// Get reboot reason magic.
|
||||
magic[0] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG);
|
||||
magic[1] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG);
|
||||
|
||||
// Magic must be correct and match on both registers.
|
||||
if (magic[0] != RTC_REBOOT_REASON_MAGIC || magic[0] != magic[1])
|
||||
return false;
|
||||
|
||||
// Reboot reason setter is expected to have updated the actual regs already.
|
||||
rr->enc.val1 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG);
|
||||
rr->enc.val2 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG);
|
||||
|
||||
// Clear magic and update actual regs.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
|
||||
|
||||
// Return reboot reason. False if [config] was selected.
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
#define MAX77620_RTC_NR_TIME_REGS 7
|
||||
|
||||
#define MAX77620_RTC_RTCINT_REG 0x00
|
||||
#define MAX77620_RTC_RTCINTM_REG 0x01
|
||||
#define MAX77620_RTC_CONTROLM_REG 0x02
|
||||
#define MAX77620_RTC_CONTROL_REG 0x03
|
||||
#define MAX77620_RTC_BIN_FORMAT BIT(0)
|
||||
|
@ -34,6 +36,9 @@
|
|||
#define MAX77620_RTC_WRITE_UPDATE BIT(0)
|
||||
#define MAX77620_RTC_READ_UPDATE BIT(4)
|
||||
|
||||
#define MAX77620_RTC_UPDATE1_REG 0x05
|
||||
#define MAX77620_RTC_RTCSMPL_REG 0x06
|
||||
|
||||
#define MAX77620_RTC_SEC_REG 0x07
|
||||
#define MAX77620_RTC_MIN_REG 0x08
|
||||
#define MAX77620_RTC_HOUR_REG 0x09
|
||||
|
@ -69,9 +74,47 @@ typedef struct _rtc_time_t {
|
|||
u16 year;
|
||||
} rtc_time_t;
|
||||
|
||||
#define RTC_REBOOT_REASON_MAGIC 0x77 // 7-bit reg.
|
||||
|
||||
enum {
|
||||
REBOOT_REASON_NOP = 0, // Use [config].
|
||||
REBOOT_REASON_SELF = 1, // Use autoboot_idx/autoboot_list.
|
||||
REBOOT_REASON_MENU = 2, // Force menu.
|
||||
REBOOT_REASON_UMS = 3, // Force selected UMS partition.
|
||||
REBOOT_REASON_REC = 4, // Set PMC_SCRATCH0_MODE_RECOVERY and reboot to self.
|
||||
REBOOT_REASON_PANIC = 5 // Inform bootloader that panic occured if T210B01.
|
||||
};
|
||||
|
||||
typedef struct _rtc_rr_decoded_t
|
||||
{
|
||||
u16 reason:4;
|
||||
u16 autoboot_idx:4;
|
||||
u16 autoboot_list:1;
|
||||
u16 ums_idx:3;
|
||||
} rtc_rr_decoded_t;
|
||||
|
||||
typedef struct _rtc_rr_encoded_t
|
||||
{
|
||||
u16 val1:6; // 6-bit reg.
|
||||
u16 val2:6; // 6-bit reg.
|
||||
} rtc_rr_encoded_t;
|
||||
|
||||
typedef struct _rtc_reboot_reason_t
|
||||
{
|
||||
union {
|
||||
rtc_rr_decoded_t dec;
|
||||
rtc_rr_encoded_t enc;
|
||||
};
|
||||
} rtc_reboot_reason_t;
|
||||
|
||||
void max77620_rtc_prep_read();
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
|
||||
void max77620_rtc_set_epoch_offset(int offset);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr);
|
||||
bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr);
|
||||
|
||||
#endif /* _MFD_MAX77620_RTC_H_ */
|
||||
|
|
603
bdk/sec/se.c
603
bdk/sec/se.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,12 +18,13 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "se.h"
|
||||
#include "se_t210.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
typedef struct _se_ll_t
|
||||
{
|
||||
|
@ -32,6 +33,9 @@ typedef struct _se_ll_t
|
|||
vu32 size;
|
||||
} se_ll_t;
|
||||
|
||||
se_ll_t ll_src, ll_dst;
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
|
||||
|
||||
static void _gf256_mul_x(void *block)
|
||||
{
|
||||
u8 *pdata = (u8 *)block;
|
||||
|
@ -48,69 +52,75 @@ static void _gf256_mul_x(void *block)
|
|||
pdata[0xF] ^= 0x87;
|
||||
}
|
||||
|
||||
static void _gf256_mul_x_le(void *block)
|
||||
{
|
||||
u32 *pdata = (u32 *)block;
|
||||
u32 carry = 0;
|
||||
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
{
|
||||
u32 b = pdata[i];
|
||||
pdata[i] = (b << 1) | carry;
|
||||
carry = b >> 31;
|
||||
}
|
||||
|
||||
if (carry)
|
||||
pdata[0x0] ^= 0x87;
|
||||
}
|
||||
|
||||
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
|
||||
{
|
||||
ll->num = 0;
|
||||
ll->num = 0;
|
||||
ll->addr = addr;
|
||||
ll->size = size;
|
||||
}
|
||||
|
||||
static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
|
||||
static void _se_ll_set(se_ll_t *src, se_ll_t *dst)
|
||||
{
|
||||
SE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;
|
||||
SE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;
|
||||
SE(SE_IN_LL_ADDR_REG) = (u32)src;
|
||||
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
|
||||
}
|
||||
|
||||
static int _se_wait()
|
||||
{
|
||||
while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// Wait for operation to be done.
|
||||
while (!(SE(SE_INT_STATUS_REG) & SE_INT_OP_DONE))
|
||||
;
|
||||
if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
|
||||
SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN ||
|
||||
SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR)
|
||||
|
||||
// Check for errors.
|
||||
if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
|
||||
(SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
|
||||
(SE(SE_ERR_STATUS_REG) != 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
se_ll_t *ll_dst, *ll_src;
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_dst = NULL;
|
||||
ll_src = NULL;
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_dst, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
if (src)
|
||||
// T210B01: IRAM/TZRAM/DRAM AHB coherency WAR.
|
||||
if (!tegra_t210 && ll_dst_ptr)
|
||||
{
|
||||
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_src, (u32)src, src_size);
|
||||
}
|
||||
u32 timeout = get_tmr_us() + 1000000;
|
||||
// Ensure data is out from SE.
|
||||
while (SE(SE_STATUS_REG) & SE_STATUS_MEM_IF_BUSY)
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_dst, ll_src);
|
||||
|
||||
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
|
||||
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
|
||||
|
||||
if (is_oneshot)
|
||||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
if (src)
|
||||
free(ll_src);
|
||||
if (dst)
|
||||
free(ll_dst);
|
||||
|
||||
return res;
|
||||
// Ensure data is out from AHB.
|
||||
if (ll_dst_ptr->addr >= DRAM_START)
|
||||
{
|
||||
timeout = get_tmr_us() + 200000;
|
||||
while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID)
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -120,22 +130,48 @@ static int _se_execute_finalize()
|
|||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
// Invalidate data after OP is done.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
if (ll_src)
|
||||
{
|
||||
free(ll_src);
|
||||
ll_src = NULL;
|
||||
}
|
||||
if (ll_dst)
|
||||
{
|
||||
free(ll_dst);
|
||||
ll_dst = NULL;
|
||||
}
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src_ptr = &ll_src;
|
||||
_se_ll_init(ll_src_ptr, (u32)src, src_size);
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst_ptr = &ll_dst;
|
||||
_se_ll_init(ll_dst_ptr, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_src_ptr, ll_dst_ptr);
|
||||
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
// Flush data before starting OP.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG) = op;
|
||||
|
||||
if (is_oneshot)
|
||||
return _se_execute_finalize();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
return _se_execute(op, dst, dst_size, src, src_size, true);
|
||||
|
@ -146,83 +182,82 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||
if (!src || !dst)
|
||||
return 0;
|
||||
|
||||
u8 *block = (u8 *)malloc(0x10);
|
||||
memset(block, 0, 0x10);
|
||||
u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
memcpy(block, src, src_size);
|
||||
int res = _se_execute_oneshot(op, block, 0x10, block, 0x10);
|
||||
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
||||
memcpy(dst, block, dst_size);
|
||||
|
||||
free(block);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _se_aes_ctr_set(void *ctr)
|
||||
static void _se_aes_ctr_set(const void *ctr)
|
||||
{
|
||||
u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
|
||||
memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE);
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
memcpy(data, ctr, SE_AES_IV_SIZE);
|
||||
|
||||
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
|
||||
SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i];
|
||||
for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++)
|
||||
SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i];
|
||||
}
|
||||
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||
{
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) =
|
||||
((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
|
||||
((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs);
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
|
||||
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||
SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG;
|
||||
if (flags & SE_RSA_KEY_LOCK_FLAG)
|
||||
SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
|
||||
}
|
||||
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||
{
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks);
|
||||
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags;
|
||||
if (flags & SE_KEY_LOCK_FLAG)
|
||||
SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks);
|
||||
}
|
||||
|
||||
u32 se_key_acc_ctrl_get(u32 ks)
|
||||
{
|
||||
return SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks);
|
||||
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
|
||||
}
|
||||
|
||||
void se_aes_key_set(u32 ks, void *key, u32 size)
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size)
|
||||
{
|
||||
u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||
memcpy(data, key, size);
|
||||
|
||||
for (u32 i = 0; i < (size / 4); i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_set(u32 ks, void *iv)
|
||||
void se_aes_iv_set(u32 ks, const void *iv)
|
||||
{
|
||||
u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
|
||||
memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE);
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
memcpy(data, iv, SE_AES_IV_SIZE);
|
||||
|
||||
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_key_get(u32 ks, void *key, u32 size)
|
||||
{
|
||||
u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||
|
||||
for (u32 i = 0; i < (size / 4); i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
|
||||
data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG);
|
||||
}
|
||||
|
||||
memcpy(key, data, size);
|
||||
|
@ -230,78 +265,107 @@ void se_aes_key_get(u32 ks, void *key, u32 size)
|
|||
|
||||
void se_aes_key_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
{
|
||||
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
|
||||
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_updated_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
||||
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
return _se_execute_oneshot(OP_START, NULL, 0, input, 0x10);
|
||||
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
|
||||
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
|
||||
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||
}
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
}
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
}
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
|
||||
{
|
||||
return se_aes_crypt_ecb(ks, enc, dst, 0x10, src, 0x10);
|
||||
return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)
|
||||
{
|
||||
SE(SE_SPARE_0_REG_OFFSET) = 1;
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);
|
||||
SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
|
||||
SE_CRYPTO_CTR_CNTN(1);
|
||||
_se_aes_ctr_set(ctr);
|
||||
|
||||
u32 src_size_aligned = src_size & 0xFFFFFFF0;
|
||||
|
@ -309,47 +373,47 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
|
|||
|
||||
if (src_size_aligned)
|
||||
{
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
|
||||
if (!_se_execute_oneshot(OP_START, dst, dst_size, src, src_size_aligned))
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_size - src_size_aligned && src_size_aligned < dst_size)
|
||||
return _se_execute_one_block(OP_START, dst + src_size_aligned,
|
||||
return _se_execute_one_block(SE_OP_START, dst + src_size_aligned,
|
||||
MIN(src_size_delta, dst_size - src_size_aligned),
|
||||
src + src_size_aligned, src_size_delta);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *tweak = (u8 *)malloc(0x10);
|
||||
u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||
u8 *pdst = (u8 *)dst;
|
||||
u8 *psrc = (u8 *)src;
|
||||
|
||||
//Generate tweak.
|
||||
// Generate tweak.
|
||||
for (int i = 0xF; i >= 0; i--)
|
||||
{
|
||||
tweak[i] = sec & 0xFF;
|
||||
sec >>= 8;
|
||||
}
|
||||
if (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak))
|
||||
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||
goto out;
|
||||
|
||||
//We are assuming a 0x10-aligned sector size in this implementation.
|
||||
for (u32 i = 0; i < secsize / 0x10; i++)
|
||||
// We are assuming a 0x10-aligned sector size in this implementation.
|
||||
for (u32 i = 0; i < secsize / SE_AES_BLOCK_SIZE; i++)
|
||||
{
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
|
||||
pdst[j] = psrc[j] ^ tweak[j];
|
||||
if (!se_aes_crypt_block_ecb(ks2, enc, pdst, pdst))
|
||||
if (!se_aes_crypt_block_ecb(crypt_ks, enc, pdst, pdst))
|
||||
goto out;
|
||||
for (u32 j = 0; j < 0x10; j++)
|
||||
for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
|
||||
pdst[j] = pdst[j] ^ tweak[j];
|
||||
_gf256_mul_x(tweak);
|
||||
psrc += 0x10;
|
||||
pdst += 0x10;
|
||||
psrc += SE_AES_BLOCK_SIZE;
|
||||
pdst += SE_AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
res = 1;
|
||||
|
@ -359,78 +423,146 @@ out:;
|
|||
return res;
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
|
||||
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size)
|
||||
{
|
||||
u32 *pdst = (u32 *)dst;
|
||||
u32 *psrc = (u32 *)src;
|
||||
u32 *ptweak = (u32 *)tweak;
|
||||
|
||||
if (regen_tweak)
|
||||
{
|
||||
for (int i = 0xF; i >= 0; i--)
|
||||
{
|
||||
tweak[i] = sec & 0xFF;
|
||||
sec >>= 8;
|
||||
}
|
||||
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls.
|
||||
for (u32 i = 0; i < (tweak_exp << 5); i++)
|
||||
_gf256_mul_x_le(tweak);
|
||||
|
||||
u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4)));
|
||||
memcpy(orig_tweak, tweak, SE_KEY_128_SIZE);
|
||||
|
||||
// We are assuming a 16 sector aligned size in this implementation.
|
||||
for (u32 i = 0; i < (sec_size >> 4); i++)
|
||||
{
|
||||
for (u32 j = 0; j < 4; j++)
|
||||
pdst[j] = psrc[j] ^ ptweak[j];
|
||||
|
||||
_gf256_mul_x_le(tweak);
|
||||
psrc += 4;
|
||||
pdst += 4;
|
||||
}
|
||||
|
||||
if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size))
|
||||
return 0;
|
||||
|
||||
pdst = (u32 *)dst;
|
||||
ptweak = (u32 *)orig_tweak;
|
||||
for (u32 i = 0; i < (sec_size >> 4); i++)
|
||||
{
|
||||
for (u32 j = 0; j < 4; j++)
|
||||
pdst[j] = pdst[j] ^ ptweak[j];
|
||||
|
||||
_gf256_mul_x_le(orig_tweak);
|
||||
pdst += 4;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
|
||||
{
|
||||
u8 *pdst = (u8 *)dst;
|
||||
u8 *psrc = (u8 *)src;
|
||||
|
||||
for (u32 i = 0; i < num_secs; i++)
|
||||
if (!se_aes_xts_crypt_sec(ks1, ks2, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
|
||||
if (!se_aes_xts_crypt_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
|
||||
{
|
||||
u32 hash32[SE_SHA_256_SIZE / 4];
|
||||
|
||||
// Backup message left.
|
||||
if (msg_left)
|
||||
{
|
||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
||||
}
|
||||
|
||||
// Copy output hash.
|
||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
||||
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
||||
}
|
||||
|
||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
|
||||
{
|
||||
int res;
|
||||
u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
|
||||
u32 hash32[SE_SHA_256_SIZE / 4];
|
||||
|
||||
//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256.
|
||||
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
||||
return 0;
|
||||
|
||||
// Src size of 0 is not supported, so return null string sha256.
|
||||
// if (!src_size)
|
||||
// {
|
||||
// const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
// };
|
||||
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// Setup config for SHA256.
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg;
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_SHA_CONFIG_REG) = sha_cfg;
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
// Set total size to current buffer size if empty.
|
||||
if (!total_size)
|
||||
total_size = src_size;
|
||||
|
||||
// Set total size: BITS(src_size), up to 2 EB.
|
||||
SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29);
|
||||
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_0_REG) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LENGTH_1_REG) = (u32)(total_size >> 29);
|
||||
SE(SE_SHA_MSG_LENGTH_2_REG) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_3_REG) = 0;
|
||||
|
||||
// Set size left to hash.
|
||||
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29);
|
||||
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(total_size >> 29);
|
||||
SE(SE_SHA_MSG_LEFT_2_REG) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_3_REG) = 0;
|
||||
|
||||
// If we hash in chunks, copy over the intermediate.
|
||||
if (sha_cfg == SHA_CONTINUE && msg_left)
|
||||
{
|
||||
// Restore message left to process.
|
||||
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0];
|
||||
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
|
||||
SE(SE_SHA_MSG_LEFT_0_REG) = msg_left[0];
|
||||
SE(SE_SHA_MSG_LEFT_1_REG) = msg_left[1];
|
||||
|
||||
// Restore hash reg.
|
||||
memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE);
|
||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
||||
SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
|
||||
memcpy(hash32, hash, SE_SHA_256_SIZE);
|
||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||
SE(SE_HASH_RESULT_REG + (i * 4)) = byte_swap_32(hash32[i]);
|
||||
}
|
||||
|
||||
// Trigger the operation.
|
||||
res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot);
|
||||
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
|
||||
|
||||
if (is_oneshot)
|
||||
{
|
||||
// Backup message left.
|
||||
if (msg_left)
|
||||
{
|
||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
|
||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
|
||||
}
|
||||
|
||||
// Copy output hash.
|
||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
|
||||
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
|
||||
}
|
||||
se_calc_sha256_get_hash(hash, msg_left);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -442,20 +574,9 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
|
|||
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
||||
{
|
||||
u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
|
||||
int res = _se_execute_finalize();
|
||||
|
||||
// Backup message left.
|
||||
if (msg_left)
|
||||
{
|
||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
|
||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
|
||||
}
|
||||
|
||||
// Copy output hash.
|
||||
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
|
||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
|
||||
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
|
||||
se_calc_sha256_get_hash(hash, msg_left);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -463,18 +584,17 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
|||
int se_gen_prng128(void *dst)
|
||||
{
|
||||
// Setup config for X931 PRNG.
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
|
||||
//SE(SE_RNG_SRC_CONFIG_REG) =
|
||||
// SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE);
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG) = 1;
|
||||
|
||||
SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL);
|
||||
//SE(SE_RNG_SRC_CONFIG_REG_OFFSET) =
|
||||
// SE_RNG_SRC_CONFIG_ENT_SRC(RNG_SRC_RO_ENT_ENABLE) | SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE);
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG_OFFSET) = 1;
|
||||
|
||||
SE(SE_BLOCK_COUNT_REG_OFFSET) = (16 >> 4) - 1;
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1;
|
||||
|
||||
// Trigger the operation.
|
||||
return _se_execute_oneshot(OP_START, dst, 16, NULL, 0);
|
||||
return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0);
|
||||
}
|
||||
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
|
@ -482,43 +602,43 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
|
||||
|
||||
// Set Secure Random Key.
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(OP_START, NULL, 0, NULL, 0);
|
||||
_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0);
|
||||
|
||||
// Save AES keys.
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
|
||||
for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++)
|
||||
for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
|
||||
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
|
||||
memcpy(keys + i * keysize, aligned_buf, 0x10);
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
memcpy(keys + i * keysize, aligned_buf, SE_AES_BLOCK_SIZE);
|
||||
|
||||
if (keysize > 0x10)
|
||||
if (keysize > SE_KEY_128_SIZE)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
|
||||
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
|
||||
memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
memcpy(keys + i * keysize + SE_AES_BLOCK_SIZE, aligned_buf, SE_AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Save SRK to PMC secure scratches.
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(SRK);
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||
|
||||
// End context save.
|
||||
SE(SE_CONFIG_REG_OFFSET) = 0;
|
||||
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||
SE(SE_CONFIG_REG) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
|
||||
|
||||
// Get SRK.
|
||||
u32 srk[4];
|
||||
|
@ -529,7 +649,66 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
|
||||
// Decrypt context.
|
||||
se_aes_key_clear(3);
|
||||
se_aes_key_set(3, srk, 0x10);
|
||||
se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize);
|
||||
se_aes_key_set(3, srk, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
||||
se_aes_key_clear(3);
|
||||
}
|
||||
|
||||
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
|
||||
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
|
||||
// Generate sub key
|
||||
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
|
||||
goto out;
|
||||
|
||||
_gf256_mul_x(key);
|
||||
if (src_size & 0xF)
|
||||
_gf256_mul_x(key);
|
||||
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
|
||||
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
|
||||
u32 num_blocks = (src_size + 0xf) >> 4;
|
||||
if (num_blocks > 1)
|
||||
{
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
|
||||
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
|
||||
goto out;
|
||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
|
||||
}
|
||||
|
||||
if (src_size & 0xf)
|
||||
{
|
||||
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
|
||||
last_block[src_size & 0xf] = 0x80;
|
||||
}
|
||||
else if (src_size >= SE_AES_BLOCK_SIZE)
|
||||
{
|
||||
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
|
||||
last_block[i] ^= key[i];
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
|
||||
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
|
||||
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
|
||||
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
|
||||
|
||||
out:;
|
||||
free(key);
|
||||
free(last_block);
|
||||
return res;
|
||||
}
|
||||
|
|
58
bdk/sec/se.h
58
bdk/sec/se.h
|
@ -1,41 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SE_H_
|
||||
#define _SE_H_
|
||||
|
||||
#include "se_t210.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags);
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||
u32 se_key_acc_ctrl_get(u32 ks);
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||
void se_aes_key_set(u32 ks, void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, void *iv);
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, const void *iv);
|
||||
void se_aes_key_get(u32 ks, void *key, u32 size);
|
||||
void se_aes_key_clear(u32 ks);
|
||||
void se_aes_iv_clear(u32 ks);
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
|
||||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
||||
int se_gen_prng128(void *dst);
|
||||
void se_aes_iv_updated_clear(u32 ks);
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
||||
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
||||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize);
|
||||
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
|
||||
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
|
||||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
||||
int se_gen_prng128(void *dst);
|
||||
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,400 +1,328 @@
|
|||
/*
|
||||
* Driver for Tegra Security Engine
|
||||
*
|
||||
* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_TEGRA_SE_H
|
||||
#define _CRYPTO_TEGRA_SE_H
|
||||
#ifndef _SE_T210_H
|
||||
#define _SE_T210_H
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define TEGRA_SE_CRA_PRIORITY 300
|
||||
#define TEGRA_SE_COMPOSITE_PRIORITY 400
|
||||
#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50
|
||||
#define SE_MAX_SRC_SG_COUNT 50
|
||||
#define SE_MAX_DST_SG_COUNT 50
|
||||
#define SE_CRYPTO_QUEUE_LENGTH 50
|
||||
#define SE_MAX_SRC_SG_COUNT 50
|
||||
#define SE_MAX_DST_SG_COUNT 50
|
||||
|
||||
#define TEGRA_SE_KEYSLOT_COUNT 16
|
||||
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
|
||||
#define SE_AES_KEYSLOT_COUNT 16
|
||||
#define SE_RSA_KEYSLOT_COUNT 2
|
||||
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
|
||||
|
||||
#define SE_AES_BLOCK_SIZE 16
|
||||
#define SE_AES_IV_SIZE 16
|
||||
#define SE_AES_MIN_KEY_SIZE 16
|
||||
#define SE_AES_MAX_KEY_SIZE 32
|
||||
#define SE_KEY_128_SIZE 16
|
||||
#define SE_KEY_192_SIZE 24
|
||||
#define SE_KEY_256_SIZE 32
|
||||
#define SE_SHA_192_SIZE 24
|
||||
#define SE_SHA_256_SIZE 32
|
||||
#define SE_SHA_384_SIZE 48
|
||||
#define SE_SHA_512_SIZE 64
|
||||
#define SE_RNG_IV_SIZE 16
|
||||
#define SE_RNG_DT_SIZE 16
|
||||
#define SE_RNG_KEY_SIZE 16
|
||||
#define SE_RNG_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE)
|
||||
|
||||
#define SE_AES_CMAC_DIGEST_SIZE 16
|
||||
#define SE_RSA512_DIGEST_SIZE 64
|
||||
#define SE_RSA1024_DIGEST_SIZE 128
|
||||
#define SE_RSA1536_DIGEST_SIZE 192
|
||||
#define SE_RSA2048_DIGEST_SIZE 256
|
||||
|
||||
#define DECRYPT 0
|
||||
#define ENCRYPT 1
|
||||
|
||||
/* SE register definitions */
|
||||
#define SE_SECURITY_0 0x000
|
||||
#define SE_KEY_SCHED_READ_SHIFT 3
|
||||
#define SE_SE_SECURITY_REG 0x000
|
||||
#define SE_HARD_SETTING BIT(0)
|
||||
#define SE_ENG_DIS BIT(1)
|
||||
#define SE_PERKEY_SETTING BIT(2)
|
||||
#define SE_SOFT_SETTING BIT(16)
|
||||
|
||||
#define SE_TZRAM_SECURITY_0 0x004
|
||||
#define SE_TZRAM_SECURITY_REG 0x004
|
||||
#define SE_TZRAM_HARD_SETTING BIT(0)
|
||||
#define SE_TZRAM_ENG_DIS BIT(1)
|
||||
|
||||
#define SE_CONFIG_REG_OFFSET 0x014
|
||||
#define SE_CONFIG_ENC_ALG_SHIFT 12
|
||||
#define SE_CONFIG_DEC_ALG_SHIFT 8
|
||||
#define ALG_AES_ENC 1
|
||||
#define ALG_RNG 2
|
||||
#define ALG_SHA 3
|
||||
#define ALG_RSA 4
|
||||
#define ALG_NOP 0
|
||||
#define ALG_AES_DEC 1
|
||||
#define SE_CONFIG_ENC_ALG(x) ((x) << SE_CONFIG_ENC_ALG_SHIFT)
|
||||
#define SE_CONFIG_DEC_ALG(x) ((x) << SE_CONFIG_DEC_ALG_SHIFT)
|
||||
#define SE_CONFIG_DST_SHIFT 2
|
||||
#define DST_MEMORY 0
|
||||
#define DST_HASHREG 1
|
||||
#define DST_KEYTAB 2
|
||||
#define DST_SRK 3
|
||||
#define DST_RSAREG 4
|
||||
#define SE_CONFIG_DST(x) ((x) << SE_CONFIG_DST_SHIFT)
|
||||
#define SE_CONFIG_ENC_MODE_SHIFT 24
|
||||
#define SE_CONFIG_DEC_MODE_SHIFT 16
|
||||
#define MODE_KEY128 0
|
||||
#define MODE_KEY192 1
|
||||
#define MODE_KEY256 2
|
||||
#define MODE_SHA1 0
|
||||
#define MODE_SHA224 4
|
||||
#define MODE_SHA256 5
|
||||
#define MODE_SHA384 6
|
||||
#define MODE_SHA512 7
|
||||
#define SE_CONFIG_ENC_MODE(x) ((x) << SE_CONFIG_ENC_MODE_SHIFT)
|
||||
#define SE_CONFIG_DEC_MODE(x) ((x) << SE_CONFIG_DEC_MODE_SHIFT)
|
||||
#define SE_OPERATION_REG 0x008
|
||||
#define SE_OP_ABORT 0
|
||||
#define SE_OP_START 1
|
||||
#define SE_OP_RESTART_OUT 2
|
||||
#define SE_OP_CTX_SAVE 3
|
||||
#define SE_OP_RESTART_IN 4
|
||||
|
||||
#define SE_RNG_CONFIG_REG_OFFSET 0x340
|
||||
#define RNG_MODE_SHIFT 0
|
||||
#define RNG_MODE_NORMAL 0
|
||||
#define RNG_MODE_FORCE_INSTANTION 1
|
||||
#define RNG_MODE_FORCE_RESEED 2
|
||||
#define SE_RNG_CONFIG_MODE(x) ((x) << RNG_MODE_SHIFT)
|
||||
#define RNG_SRC_SHIFT 2
|
||||
#define RNG_SRC_NONE 0
|
||||
#define RNG_SRC_ENTROPY 1
|
||||
#define RNG_SRC_LFSR 2
|
||||
#define SE_RNG_CONFIG_SRC(x) ((x) << RNG_SRC_SHIFT)
|
||||
#define SE_INT_ENABLE_REG 0x00C
|
||||
#define SE_INT_STATUS_REG 0x010
|
||||
#define SE_INT_IN_LL_BUF_RD BIT(0)
|
||||
#define SE_INT_IN_DONE BIT(1)
|
||||
#define SE_INT_OUT_LL_BUF_WR BIT(2)
|
||||
#define SE_INT_OUT_DONE BIT(3)
|
||||
#define SE_INT_OP_DONE BIT(4)
|
||||
#define SE_INT_RESEED_NEEDED BIT(5)
|
||||
#define SE_INT_ERR_STAT BIT(16)
|
||||
|
||||
#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344
|
||||
#define RNG_SRC_RO_ENT_SHIFT 1
|
||||
#define RNG_SRC_RO_ENT_ENABLE 1
|
||||
#define RNG_SRC_RO_ENT_DISABLE 0
|
||||
#define SE_RNG_SRC_CONFIG_ENT_SRC(x) ((x) << RNG_SRC_RO_ENT_SHIFT)
|
||||
#define RNG_SRC_RO_ENT_LOCK_SHIFT 0
|
||||
#define RNG_SRC_RO_ENT_LOCK_ENABLE 1
|
||||
#define RNG_SRC_RO_ENT_LOCK_DISABLE 0
|
||||
#define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) ((x) << RNG_SRC_RO_ENT_LOCK_SHIFT)
|
||||
#define SE_CONFIG_REG 0x014
|
||||
#define DST_MEMORY 0
|
||||
#define DST_HASHREG 1
|
||||
#define DST_KEYTABLE 2
|
||||
#define DST_SRK 3
|
||||
#define DST_RSAREG 4
|
||||
#define SE_CONFIG_DST(x) ((x) << 2)
|
||||
#define ALG_NOP 0
|
||||
#define ALG_AES_DEC 1
|
||||
#define SE_CONFIG_DEC_ALG(x) ((x) << 8)
|
||||
#define ALG_NOP 0
|
||||
#define ALG_AES_ENC 1
|
||||
#define ALG_RNG 2
|
||||
#define ALG_SHA 3
|
||||
#define ALG_RSA 4
|
||||
#define SE_CONFIG_ENC_ALG(x) ((x) << 12)
|
||||
#define MODE_KEY128 0
|
||||
#define MODE_KEY192 1
|
||||
#define MODE_KEY256 2
|
||||
#define MODE_SHA1 0
|
||||
#define MODE_SHA224 4
|
||||
#define MODE_SHA256 5
|
||||
#define MODE_SHA384 6
|
||||
#define MODE_SHA512 7
|
||||
#define SE_CONFIG_DEC_MODE(x) ((x) << 16)
|
||||
#define SE_CONFIG_ENC_MODE(x) ((x) << 24)
|
||||
|
||||
#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348
|
||||
#define SE_IN_LL_ADDR_REG 0x018
|
||||
#define SE_IN_CUR_BYTE_ADDR_REG 0x01C
|
||||
#define SE_IN_CUR_LL_ID_REG 0x020
|
||||
#define SE_OUT_LL_ADDR_REG 0x024
|
||||
#define SE_OUT_CUR_BYTE_ADDR_REG 0x028
|
||||
#define SE_OUT_CUR_LL_ID_REG 0x02C
|
||||
|
||||
#define SE_KEYTABLE_REG_OFFSET 0x31c
|
||||
#define SE_KEYTABLE_SLOT_SHIFT 4
|
||||
#define SE_KEYTABLE_SLOT(x) ((x) << SE_KEYTABLE_SLOT_SHIFT)
|
||||
#define SE_KEYTABLE_QUAD_SHIFT 2
|
||||
#define QUAD_KEYS_128 0
|
||||
#define QUAD_KEYS_192 1
|
||||
#define QUAD_KEYS_256 1
|
||||
#define QUAD_ORG_IV 2
|
||||
#define QUAD_UPDTD_IV 3
|
||||
#define SE_KEYTABLE_QUAD(x) ((x) << SE_KEYTABLE_QUAD_SHIFT)
|
||||
#define SE_KEYTABLE_OP_TYPE_SHIFT 9
|
||||
#define OP_READ 0
|
||||
#define OP_WRITE 1
|
||||
#define SE_KEYTABLE_OP_TYPE(x) ((x) << SE_KEYTABLE_OP_TYPE_SHIFT)
|
||||
#define SE_KEYTABLE_TABLE_SEL_SHIFT 8
|
||||
#define TABLE_KEYIV 0
|
||||
#define TABLE_SCHEDULE 1
|
||||
#define SE_KEYTABLE_TABLE_SEL(x) ((x) << SE_KEYTABLE_TABLE_SEL_SHIFT)
|
||||
#define SE_KEYTABLE_PKT_SHIFT 0
|
||||
#define SE_KEYTABLE_PKT(x) ((x) << SE_KEYTABLE_PKT_SHIFT)
|
||||
#define SE_HASH_RESULT_REG 0x030
|
||||
#define SE_HASH_RESULT_REG_COUNT 16
|
||||
|
||||
#define SE_OP_DONE_SHIFT 4
|
||||
#define OP_DONE 1
|
||||
#define SE_OP_DONE(x, y) ((x) && ((y) << SE_OP_DONE_SHIFT))
|
||||
#define SE_CONTEXT_SAVE_CONFIG_REG 0x070
|
||||
#define KEYS_0_3 0
|
||||
#define KEYS_4_7 1
|
||||
#define ORIGINAL_IV 2
|
||||
#define UPDATED_IV 3
|
||||
#define SE_CONTEXT_AES_WORD_QUAD(x) ((x) << 0)
|
||||
#define SE_CONTEXT_AES_KEY_INDEX(x) ((x) << 8)
|
||||
#define KEYS_0_3 0
|
||||
#define KEYS_4_7 1
|
||||
#define KEYS_8_11 2
|
||||
#define KEYS_12_15 3
|
||||
#define SE_CONTEXT_RSA_WORD_QUAD(x) ((x) << 12)
|
||||
#define SLOT0_EXPONENT 0
|
||||
#define SLOT0_MODULUS 1
|
||||
#define SLOT1_EXPONENT 2
|
||||
#define SLOT1_MODULUS 3
|
||||
#define SE_CONTEXT_RSA_KEY_INDEX(x) ((x) << 16)
|
||||
#define STICKY_0_3 0
|
||||
#define STICKY_4_7 1
|
||||
#define SE_CONTEXT_STICKY_WORD_QUAD(x) ((x) << 24)
|
||||
#define STICKY_BITS 0
|
||||
#define RSA_KEYTABLE 1
|
||||
#define AES_KEYTABLE 2
|
||||
#define MEM 4
|
||||
#define SRK 6
|
||||
#define SE_CONTEXT_SRC(x) ((x) << 29)
|
||||
|
||||
#define SE_CRYPTO_LAST_BLOCK 0x080
|
||||
#define SE_CTX_SAVE_AUTO_T210B01_REG 0x074
|
||||
#define SE_CTX_SAVE_AUTO_ENABLE BIT(0)
|
||||
#define SE_CTX_SAVE_AUTO_LOCK BIT(8)
|
||||
#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16)
|
||||
|
||||
#define SE_CRYPTO_REG_OFFSET 0x304
|
||||
#define SE_CRYPTO_HASH_SHIFT 0
|
||||
#define HASH_DISABLE 0
|
||||
#define HASH_ENABLE 1
|
||||
#define SE_CRYPTO_HASH(x) ((x) << SE_CRYPTO_HASH_SHIFT)
|
||||
#define SE_CRYPTO_XOR_POS_SHIFT 1
|
||||
#define XOR_BYPASS 0
|
||||
#define XOR_TOP 2
|
||||
#define XOR_BOTTOM 3
|
||||
#define SE_CRYPTO_XOR_POS(x) ((x) << SE_CRYPTO_XOR_POS_SHIFT)
|
||||
#define SE_CRYPTO_INPUT_SEL_SHIFT 3
|
||||
#define INPUT_AHB 0
|
||||
#define INPUT_RANDOM 1
|
||||
#define INPUT_AESOUT 2
|
||||
#define INPUT_LNR_CTR 3
|
||||
#define SE_CRYPTO_INPUT_SEL(x) ((x) << SE_CRYPTO_INPUT_SEL_SHIFT)
|
||||
#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5
|
||||
#define VCTRAM_AHB 0
|
||||
#define VCTRAM_AESOUT 2
|
||||
#define VCTRAM_PREVAHB 3
|
||||
#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
|
||||
#define SE_CRYPTO_IV_SEL_SHIFT 7
|
||||
#define IV_ORIGINAL 0
|
||||
#define IV_UPDATED 1
|
||||
#define SE_CRYPTO_IV_SEL(x) ((x) << SE_CRYPTO_IV_SEL_SHIFT)
|
||||
#define SE_CRYPTO_CORE_SEL_SHIFT 8
|
||||
#define CORE_DECRYPT 0
|
||||
#define CORE_ENCRYPT 1
|
||||
#define SE_CRYPTO_CORE_SEL(x) ((x) << SE_CRYPTO_CORE_SEL_SHIFT)
|
||||
#define SE_CRYPTO_CTR_VAL_SHIFT 11
|
||||
#define SE_CRYPTO_CTR_VAL(x) ((x) << SE_CRYPTO_CTR_VAL_SHIFT)
|
||||
#define SE_CRYPTO_KEY_INDEX_SHIFT 24
|
||||
#define SE_CRYPTO_KEY_INDEX(x) ((x) << SE_CRYPTO_KEY_INDEX_SHIFT)
|
||||
#define SE_CRYPTO_CTR_CNTN_SHIFT 11
|
||||
#define SE_CRYPTO_CTR_CNTN(x) ((x) << SE_CRYPTO_CTR_CNTN_SHIFT)
|
||||
#define SE_CRYPTO_LAST_BLOCK 0x080
|
||||
|
||||
#define SE_CRYPTO_CTR_REG_COUNT 4
|
||||
#define SE_CRYPTO_CTR_REG_OFFSET 0x308
|
||||
|
||||
#define SE_OPERATION_REG_OFFSET 0x008
|
||||
#define SE_OPERATION_SHIFT 0
|
||||
#define OP_ABORT 0
|
||||
#define OP_START 1
|
||||
#define OP_RESTART 2
|
||||
#define OP_CTX_SAVE 3
|
||||
#define OP_RESTART_IN 4
|
||||
#define SE_OPERATION(x) ((x) << SE_OPERATION_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070
|
||||
#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0
|
||||
#define KEYS_0_3 0
|
||||
#define KEYS_4_7 1
|
||||
#define ORIG_IV 2
|
||||
#define UPD_IV 3
|
||||
#define SE_CONTEXT_SAVE_WORD_QUAD(x) ((x) << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8
|
||||
#define SE_CONTEXT_SAVE_KEY_INDEX(x) ((x) << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT 24
|
||||
#define STICKY_0_3 0
|
||||
#define STICKY_4_7 1
|
||||
#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \
|
||||
((x) << SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_SAVE_SRC_SHIFT 29
|
||||
#define STICKY_BITS 0
|
||||
#define KEYTABLE 2
|
||||
#define MEM 4
|
||||
#define SRK 6
|
||||
|
||||
#define RSA_KEYTABLE 1
|
||||
#define AES_KEYTABLE 2
|
||||
#define SE_CONTEXT_SAVE_SRC(x) ((x) << SE_CONTEXT_SAVE_SRC_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16
|
||||
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \
|
||||
((x) << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)
|
||||
|
||||
#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12
|
||||
#define SE_CONTEXT_RSA_WORD_QUAD(x) \
|
||||
((x) << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)
|
||||
|
||||
#define SE_CTX_SAVE_AUTO 0x074
|
||||
#define CTX_SAVE_AUTO_ENABLE BIT(0)
|
||||
#define CTX_SAVE_AUTO_LOCK BIT(8)
|
||||
#define CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16)
|
||||
|
||||
#define SE_INT_ENABLE_REG_OFFSET 0x00c
|
||||
#define SE_INT_STATUS_REG_OFFSET 0x010
|
||||
#define INT_DISABLE 0
|
||||
#define INT_ENABLE 1
|
||||
#define INT_UNSET 0
|
||||
#define INT_SET 1
|
||||
#define SE_INT_OP_DONE_SHIFT 4
|
||||
#define SE_INT_OP_DONE(x) ((x) << SE_INT_OP_DONE_SHIFT)
|
||||
#define SE_INT_ERROR_SHIFT 16
|
||||
#define SE_INT_ERROR(x) ((x) << SE_INT_ERROR_SHIFT)
|
||||
|
||||
#define SE_STATUS_0 0x800
|
||||
#define SE_STATUS_0_STATE_WAIT_IN 3
|
||||
|
||||
#define SE_ERR_STATUS_0 0x804
|
||||
#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0
|
||||
|
||||
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
|
||||
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
|
||||
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \
|
||||
((x) << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
|
||||
|
||||
#define SE_KEY_INDEX_SHIFT 8
|
||||
#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) ((x) << SE_KEY_INDEX_SHIFT)
|
||||
|
||||
#define SE_IN_LL_ADDR_REG_OFFSET 0x018
|
||||
#define SE_OUT_LL_ADDR_REG_OFFSET 0x024
|
||||
|
||||
#define SE_KEYTABLE_DATA0_REG_OFFSET 0x320
|
||||
#define SE_KEYTABLE_REG_MAX_DATA 16
|
||||
|
||||
#define SE_BLOCK_COUNT_REG_OFFSET 0x318
|
||||
|
||||
#define SE_SPARE_0_REG_OFFSET 0x80c
|
||||
|
||||
#define SE_SHA_CONFIG_REG_OFFSET 0x200
|
||||
#define SE_SHA_CONFIG_REG 0x200
|
||||
#define SHA_CONTINUE 0
|
||||
#define SHA_INIT_HASH 1
|
||||
|
||||
#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204
|
||||
#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208
|
||||
#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C
|
||||
#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210
|
||||
#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214
|
||||
#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218
|
||||
#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C
|
||||
#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220
|
||||
#define SE_SHA_MSG_LENGTH_0_REG 0x204
|
||||
#define SE_SHA_MSG_LENGTH_1_REG 0x208
|
||||
#define SE_SHA_MSG_LENGTH_2_REG 0x20C
|
||||
#define SE_SHA_MSG_LENGTH_3_REG 0x210
|
||||
#define SE_SHA_MSG_LEFT_0_REG 0x214
|
||||
#define SE_SHA_MSG_LEFT_1_REG 0x218
|
||||
#define SE_SHA_MSG_LEFT_2_REG 0x21C
|
||||
#define SE_SHA_MSG_LEFT_3_REG 0x220
|
||||
|
||||
#define SE_HASH_RESULT_REG_COUNT 16
|
||||
#define SE_HASH_RESULT_REG_OFFSET 0x030
|
||||
#define TEGRA_SE_KEY_256_SIZE 32
|
||||
#define TEGRA_SE_KEY_192_SIZE 24
|
||||
#define TEGRA_SE_KEY_128_SIZE 16
|
||||
#define TEGRA_SE_AES_BLOCK_SIZE 16
|
||||
#define TEGRA_SE_AES_MIN_KEY_SIZE 16
|
||||
#define TEGRA_SE_AES_MAX_KEY_SIZE 32
|
||||
#define TEGRA_SE_AES_IV_SIZE 16
|
||||
#define TEGRA_SE_SHA_512_SIZE 64
|
||||
#define TEGRA_SE_SHA_384_SIZE 48
|
||||
#define TEGRA_SE_SHA_256_SIZE 32
|
||||
#define TEGRA_SE_SHA_192_SIZE 24
|
||||
#define TEGRA_SE_RNG_IV_SIZE 16
|
||||
#define TEGRA_SE_RNG_DT_SIZE 16
|
||||
#define TEGRA_SE_RNG_KEY_SIZE 16
|
||||
#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \
|
||||
TEGRA_SE_RNG_KEY_SIZE + \
|
||||
TEGRA_SE_RNG_DT_SIZE)
|
||||
#define SE_CRYPTO_SECURITY_PERKEY_REG 0x280
|
||||
#define SE_KEY_LOCK_FLAG 0x80
|
||||
#define SE_CRYPTO_KEYTABLE_ACCESS_REG 0x284
|
||||
#define SE_CRYPTO_KEYTABLE_ACCESS_REG_COUNT 16
|
||||
#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
||||
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
||||
#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
|
||||
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
|
||||
#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
|
||||
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
|
||||
#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
|
||||
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||
|
||||
#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
|
||||
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
||||
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
|
||||
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
|
||||
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
|
||||
#define SE_CRYPTO_CONFIG_REG 0x304
|
||||
#define HASH_DISABLE 0
|
||||
#define HASH_ENABLE 1
|
||||
#define SE_CRYPTO_HASH(x) ((x) << 0)
|
||||
#define XOR_BYPASS 0
|
||||
#define XOR_TOP 2
|
||||
#define XOR_BOTTOM 3
|
||||
#define SE_CRYPTO_XOR_POS(x) ((x) << 1)
|
||||
#define INPUT_MEMORY 0
|
||||
#define INPUT_RANDOM 1
|
||||
#define INPUT_AESOUT 2
|
||||
#define INPUT_LNR_CTR 3
|
||||
#define SE_CRYPTO_INPUT_SEL(x) ((x) << 3)
|
||||
#define VCTRAM_MEM 0
|
||||
#define VCTRAM_AESOUT 2
|
||||
#define VCTRAM_PREVMEM 3
|
||||
#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << 5)
|
||||
#define IV_ORIGINAL 0
|
||||
#define IV_UPDATED 1
|
||||
#define SE_CRYPTO_IV_SEL(x) ((x) << 7)
|
||||
#define CORE_DECRYPT 0
|
||||
#define CORE_ENCRYPT 1
|
||||
#define SE_CRYPTO_CORE_SEL(x) ((x) << 8)
|
||||
#define SE_CRYPTO_KEYSCH_BYPASS BIT(10)
|
||||
#define SE_CRYPTO_CTR_CNTN(x) ((x) << 11)
|
||||
#define SE_CRYPTO_KEY_INDEX(x) ((x) << 24)
|
||||
#define MEMIF_AHB 0
|
||||
#define MEMIF_MCCIF 1
|
||||
#define SE_CRYPTO_MEMIF(x) ((x) << 31)
|
||||
|
||||
#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
|
||||
#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||
#define SE_CRYPTO_LINEAR_CTR_REG 0x308
|
||||
#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4
|
||||
|
||||
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
|
||||
#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
||||
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
||||
#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
|
||||
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
|
||||
#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
|
||||
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
|
||||
#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
|
||||
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||
#define SE_CRYPTO_BLOCK_COUNT_REG 0x318
|
||||
|
||||
#define SE_KEY_READ_DISABLE_SHIFT 0
|
||||
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
|
||||
#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C
|
||||
#define SE_KEYTABLE_PKT(x) ((x) << 0)
|
||||
#define KEYS_0_3 0
|
||||
#define KEYS_4_7 1
|
||||
#define ORIGINAL_IV 2
|
||||
#define UPDATED_IV 3
|
||||
#define SE_KEYTABLE_QUAD(x) ((x) << 2)
|
||||
#define SE_KEYTABLE_SLOT(x) ((x) << 4)
|
||||
|
||||
#define SE_CONTEXT_BUFER_SIZE 1072
|
||||
#define SE_CONTEXT_DRBG_BUFER_SIZE 2112
|
||||
#define SE_CRYPTO_KEYTABLE_DATA_REG 0x320
|
||||
|
||||
#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET 0
|
||||
#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE 16
|
||||
#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET \
|
||||
(SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)
|
||||
#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE 16
|
||||
#define SE_CRYPTO_KEYTABLE_DST_REG 0x330
|
||||
#define KEYS_0_3 0
|
||||
#define KEYS_4_7 1
|
||||
#define ORIGINAL_IV 2
|
||||
#define UPDATED_IV 3
|
||||
#define SE_KEYTABLE_DST_WORD_QUAD(x) ((x) << 0)
|
||||
#define SE_KEYTABLE_DST_KEY_INDEX(x) ((x) << 8)
|
||||
|
||||
#define SE_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
|
||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
|
||||
#define SE11_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
|
||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE + \
|
||||
SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
|
||||
#define SE_RNG_CONFIG_REG 0x340
|
||||
#define MODE_NORMAL 0
|
||||
#define MODE_FORCE_INSTANTION 1
|
||||
#define MODE_FORCE_RESEED 2
|
||||
#define SE_RNG_CONFIG_MODE(x) ((x) << 0)
|
||||
#define SRC_NONE 0
|
||||
#define SRC_ENTROPY 1
|
||||
#define SRC_LFSR 2
|
||||
#define SE_RNG_CONFIG_SRC(x) ((x) << 2)
|
||||
|
||||
#define SE_CONTEXT_SAVE_KEY_LENGTH 512
|
||||
#define SE_CONTEXT_ORIGINAL_IV_OFFSET (SE_CONTEXT_SAVE_KEYS_OFFSET + \
|
||||
SE_CONTEXT_SAVE_KEY_LENGTH)
|
||||
#define SE11_CONTEXT_ORIGINAL_IV_OFFSET (SE11_CONTEXT_SAVE_KEYS_OFFSET + \
|
||||
SE_CONTEXT_SAVE_KEY_LENGTH)
|
||||
#define SE_RNG_SRC_CONFIG_REG 0x344
|
||||
#define RO_ENTR_LOCK_DISABLE 0
|
||||
#define RO_ENTR_LOCK_ENABLE 1
|
||||
#define SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(x) ((x) << 0)
|
||||
#define RO_ENTR_DISABLE 0
|
||||
#define RO_ENTR_ENABLE 1
|
||||
#define SE_RNG_SRC_CONFIG_ENTR_SRC(x) ((x) << 1)
|
||||
#define RO_HW_DIS_CYA_DISABLE 0
|
||||
#define RO_HW_DIS_CYA_ENABLE 1
|
||||
#define SE_RNG_SRC_CONFIG_HW_DIS_CYA(x) ((x) << 2)
|
||||
#define SE_RNG_SRC_CONFIG_ENTR_SUBSMPL(x) ((x) << 4)
|
||||
#define SE_RNG_SRC_CONFIG_ENTR_DATA_FLUSH BIT(8)
|
||||
|
||||
#define SE_CONTEXT_ORIGINAL_IV_LENGTH 256
|
||||
#define SE_RNG_RESEED_INTERVAL_REG 0x348
|
||||
|
||||
#define SE_CONTEXT_UPDATED_IV_OFFSET (SE_CONTEXT_ORIGINAL_IV_OFFSET + \
|
||||
SE_CONTEXT_ORIGINAL_IV_LENGTH)
|
||||
#define SE11_CONTEXT_UPDATED_IV_OFFSET (SE11_CONTEXT_ORIGINAL_IV_OFFSET + \
|
||||
SE_CONTEXT_ORIGINAL_IV_LENGTH)
|
||||
#define SE_RSA_CONFIG 0x400
|
||||
#define RSA_KEY_SLOT_ONE 0
|
||||
#define RSA_KEY_SLOT_TW0 1
|
||||
#define RSA_KEY_SLOT(x) ((x) << 24)
|
||||
|
||||
#define SE_CONTEXT_UPDATED_IV_LENGTH 256
|
||||
#define SE_RSA_KEY_SIZE_REG 0x404
|
||||
#define RSA_KEY_WIDTH_512 0
|
||||
#define RSA_KEY_WIDTH_1024 1
|
||||
#define RSA_KEY_WIDTH_1536 2
|
||||
#define RSA_KEY_WIDTH_2048 3
|
||||
|
||||
#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \
|
||||
SE_CONTEXT_UPDATED_IV_LENGTH)
|
||||
#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \
|
||||
(SE11_CONTEXT_UPDATED_IV_OFFSET + \
|
||||
SE_CONTEXT_UPDATED_IV_LENGTH)
|
||||
#define SE_RSA_EXP_SIZE_REG 0x408
|
||||
|
||||
#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET
|
||||
#define SE_RSA_SECURITY_PERKEY_REG 0x40C
|
||||
#define SE_RSA_KEY_LOCK_FLAG 0x80
|
||||
#define SE_RSA_KEYTABLE_ACCESS_REG 0x410
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG | SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG)
|
||||
|
||||
#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH 1024
|
||||
#define SE_RSA_KEYTABLE_ADDR_REG 0x420
|
||||
#define SE_RSA_KEYTABLE_PKT(x) ((x) << 0)
|
||||
#define RSA_KEY_TYPE_EXP 0
|
||||
#define RSA_KEY_TYPE_MOD 1
|
||||
#define SE_RSA_KEYTABLE_TYPE(x) ((x) << 6)
|
||||
#define RSA_KEY_NUM(x) ((x) << 7)
|
||||
#define RSA_KEY_INPUT_MODE_REG 0
|
||||
#define RSA_KEY_INPUT_MODE_DMA 1
|
||||
#define SE_RSA_KEYTABLE_INPUT_MODE(x) ((x) << 8)
|
||||
#define RSA_KEY_READ 0
|
||||
#define RSA_KEY_WRITE 1
|
||||
#define SE_RSA_KEY_OP(x) ((x) << 10)
|
||||
|
||||
#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET \
|
||||
(SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)
|
||||
#define SE_RSA_KEYTABLE_DATA_REG 0x424
|
||||
|
||||
#define SE_CONTEXT_KNOWN_PATTERN_SIZE 16
|
||||
#define SE_RSA_OUTPUT_REG 0x428
|
||||
#define SE_RSA_OUTPUT_REG_COUNT 64
|
||||
|
||||
#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
|
||||
#define SE_STATUS_REG 0x800
|
||||
#define SE_STATUS_STATE_IDLE 0
|
||||
#define SE_STATUS_STATE_BUSY 1
|
||||
#define SE_STATUS_STATE_WAIT_OUT 2
|
||||
#define SE_STATUS_STATE_WAIT_IN 3
|
||||
#define SE_STATUS_STATE_MASK 3
|
||||
#define SE_STATUS_MEM_IF_IDLE (0 << 2)
|
||||
#define SE_STATUS_MEM_IF_BUSY BIT(2)
|
||||
|
||||
#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||
#define SE_ERR_STATUS_REG 0x804
|
||||
#define SE_ERR_STATUS_SE_NS_ACCESS BIT(0)
|
||||
#define SE_ERR_STATUS_BUSY_REG_WR BIT(1)
|
||||
#define SE_ERR_STATUS_DST BIT(2)
|
||||
#define SE_ERR_STATUS_SRK_USAGE_LIMIT BIT(3)
|
||||
#define SE_ERR_STATUS_TZRAM_NS_ACCESS BIT(24)
|
||||
#define SE_ERR_STATUS_TZRAM_ADDRESS BIT(25)
|
||||
|
||||
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT BIT(2)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F
|
||||
#define SE_MISC_REG 0x808
|
||||
#define SE_ENTROPY_NEXT_192BIT BIT(0)
|
||||
#define SE_ENTROPY_VN_BYPASS BIT(1)
|
||||
#define SE_CLK_OVR_ON BIT(2)
|
||||
|
||||
#define SE_RSA_KEYTABLE_ADDR 0x420
|
||||
#define SE_RSA_KEYTABLE_DATA 0x424
|
||||
#define SE_RSA_OUTPUT 0x428
|
||||
#define SE_SPARE_REG 0x80C
|
||||
#define SE_ERRATA_FIX_DISABLE 0
|
||||
#define SE_ERRATA_FIX_ENABLE 1
|
||||
#define SE_ECO(x) ((x) << 0)
|
||||
|
||||
#define RSA_KEY_READ 0
|
||||
#define RSA_KEY_WRITE 1
|
||||
#define SE_RSA_KEY_OP_SHIFT 10
|
||||
#define SE_RSA_KEY_OP(x) ((x) << SE_RSA_KEY_OP_SHIFT)
|
||||
|
||||
#define RSA_KEY_INPUT_MODE_REG 0
|
||||
#define RSA_KEY_INPUT_MODE_DMA 1
|
||||
#define RSA_KEY_INPUT_MODE_SHIFT 8
|
||||
#define RSA_KEY_INPUT_MODE(x) ((x) << RSA_KEY_INPUT_MODE_SHIFT)
|
||||
|
||||
#define RSA_KEY_SLOT_ONE 0
|
||||
#define RSA_KEY_SLOT_TW0 1
|
||||
#define RSA_KEY_NUM_SHIFT 7
|
||||
#define RSA_KEY_NUM(x) ((x) << RSA_KEY_NUM_SHIFT)
|
||||
|
||||
#define RSA_KEY_TYPE_EXP 0
|
||||
#define RSA_KEY_TYPE_MOD 1
|
||||
#define RSA_KEY_TYPE_SHIFT 6
|
||||
#define RSA_KEY_TYPE(x) ((x) << RSA_KEY_TYPE_SHIFT)
|
||||
|
||||
#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404
|
||||
#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408
|
||||
|
||||
#define RSA_KEY_SLOT_SHIFT 24
|
||||
#define RSA_KEY_SLOT(x) ((x) << RSA_KEY_SLOT_SHIFT)
|
||||
#define SE_RSA_CONFIG 0x400
|
||||
|
||||
#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0
|
||||
#define RSA_KEY_PKT_WORD_ADDR(x) ((x) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
|
||||
|
||||
#define RSA_KEY_WORD_ADDR_SHIFT 0
|
||||
#define RSA_KEY_WORD_ADDR(x) ((x) << RSA_KEY_WORD_ADDR_SHIFT)
|
||||
|
||||
#define SE_RSA_KEYTABLE_PKT_SHIFT 0
|
||||
#define SE_RSA_KEYTABLE_PKT(x) ((x) << SE_RSA_KEYTABLE_PKT_SHIFT)
|
||||
|
||||
#endif /* _CRYPTO_TEGRA_SE_H */
|
||||
#endif
|
||||
|
|
190
bdk/sec/tsec.c
190
bdk/sec/tsec.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -20,20 +20,23 @@
|
|||
|
||||
#include "tsec.h"
|
||||
#include "tsec_t210.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/kfuse.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
// #include <gfx_utils.h>
|
||||
|
||||
#define PKG11_MAGIC 0x31314B50
|
||||
#define KB_TSEC_FW_EMU_COMPAT 6 // KB ID for HOS 6.2.0.
|
||||
|
||||
#define TSEC_HOS_KB_620 6
|
||||
|
||||
static int _tsec_dma_wait_idle()
|
||||
{
|
||||
|
@ -55,48 +58,62 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse
|
|||
else
|
||||
cmd = TSEC_DMATRFCMD_IMEM; // DMA IMEM (Instruction memmory)
|
||||
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFFBOFFS) = pa_offset;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
|
||||
return _tsec_dma_wait_idle();
|
||||
}
|
||||
|
||||
int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *fwbuf = NULL;
|
||||
u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
|
||||
u32 type = tsec_ctxt->type;
|
||||
u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
|
||||
u32 *pkg11_magic_off;
|
||||
void *ptb;
|
||||
|
||||
bpmp_mmu_disable();
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
// Enable clocks.
|
||||
clock_enable_host1x();
|
||||
usleep(2);
|
||||
clock_enable_tsec();
|
||||
clock_enable_sor_safe();
|
||||
clock_enable_sor0();
|
||||
clock_enable_sor1();
|
||||
clock_enable_kfuse();
|
||||
|
||||
kfuse_wait_ready();
|
||||
|
||||
// Disable AHB aperture.
|
||||
mc_disable_ahb_redirect();
|
||||
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
{
|
||||
// Disable all CCPLEX core rails.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE1, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE2, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
||||
|
||||
// Enable AHB aperture and set it to full mmio.
|
||||
mc_enable_ahb_redirect();
|
||||
}
|
||||
|
||||
// Configure Falcon.
|
||||
TSEC(TSEC_DMACTL) = 0;
|
||||
TSEC(TSEC_IRQMSET) =
|
||||
TSEC_IRQMSET_EXT(0xFF) |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_SWGEN1;
|
||||
TSEC(TSEC_IRQDEST) =
|
||||
TSEC_IRQDEST_EXT(0xFF) |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_SWGEN1;
|
||||
TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN;
|
||||
if (!_tsec_dma_wait_idle())
|
||||
|
@ -106,13 +123,14 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
}
|
||||
|
||||
// Load firmware or emulate memio environment for newer TSEC fw.
|
||||
if (kb == KB_TSEC_FW_EMU_COMPAT)
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)tsec_ctxt->fw >> 8;
|
||||
else
|
||||
{
|
||||
fwbuf = (u8 *)malloc(0x4000);
|
||||
fwbuf = (u8 *)malloc(SZ_16K);
|
||||
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100);
|
||||
memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size);
|
||||
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8;
|
||||
}
|
||||
|
||||
|
@ -125,72 +143,72 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
}
|
||||
}
|
||||
|
||||
if (kb == KB_TSEC_FW_EMU_COMPAT)
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
{
|
||||
// Init SMMU translation for TSEC.
|
||||
pdir = smmu_init_for_tsec();
|
||||
smmu_init(tsec_ctxt->secmon_base);
|
||||
// Enable SMMU
|
||||
if (!smmu_is_used())
|
||||
smmu_enable();
|
||||
ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
smmu_init();
|
||||
|
||||
// Enable SMMU.
|
||||
smmu_enable();
|
||||
|
||||
// Clock reset controller.
|
||||
car = page_alloc(1);
|
||||
memcpy(car, (void *)CLOCK_BASE, 0x1000);
|
||||
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2;
|
||||
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE);
|
||||
car = smmu_page_zalloc(1);
|
||||
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
|
||||
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
|
||||
smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
|
||||
|
||||
// Fuse driver.
|
||||
fuse = page_alloc(1);
|
||||
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, 0x400);
|
||||
fuse = smmu_page_zalloc(1);
|
||||
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
|
||||
fuse[0x82C / 4] = 0;
|
||||
fuse[0x9E0 / 4] = (1 << (kb + 2)) - 1;
|
||||
fuse[0x9E4 / 4] = (1 << (kb + 2)) - 1;
|
||||
smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE);
|
||||
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
||||
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
|
||||
smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
|
||||
|
||||
// Power management controller.
|
||||
pmc = page_alloc(1);
|
||||
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE);
|
||||
pmc = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
|
||||
|
||||
// Flow control.
|
||||
flowctrl = page_alloc(1);
|
||||
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE);
|
||||
flowctrl = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
|
||||
|
||||
// Security engine.
|
||||
se = page_alloc(1);
|
||||
memcpy(se, (void *)SE_BASE, 0x1000);
|
||||
smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE);
|
||||
se = smmu_page_zalloc(1);
|
||||
memcpy(se, (void *)SE_BASE, SZ_PAGE);
|
||||
smmu_map(ptb, SE_BASE, (u32)se, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||
|
||||
// Memory controller.
|
||||
mc = page_alloc(1);
|
||||
memcpy(mc, (void *)MC_BASE, 0x1000);
|
||||
mc = smmu_page_zalloc(1);
|
||||
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
||||
mc[MC_IRAM_BOM / 4] = 0;
|
||||
mc[MC_IRAM_TOM / 4] = 0x80000000;
|
||||
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE);
|
||||
mc[MC_IRAM_TOM / 4] = DRAM_START;
|
||||
smmu_map(ptb, MC_BASE, (u32)mc, 1, SMMU_READ | SMMU_NS);
|
||||
|
||||
// IRAM
|
||||
iram = page_alloc(0x30);
|
||||
iram = smmu_page_zalloc(0x30);
|
||||
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
|
||||
// PKG1.1 magic offset.
|
||||
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4));
|
||||
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE);
|
||||
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
|
||||
smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||
|
||||
// Exception vectors
|
||||
evec = page_alloc(1);
|
||||
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE);
|
||||
evec = smmu_page_zalloc(1);
|
||||
smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
|
||||
}
|
||||
|
||||
// Execute firmware.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
|
||||
TSEC(TSEC_STATUS) = 0;
|
||||
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
TSEC(TSEC_MAILBOX1) = 0;
|
||||
TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
|
||||
if (kb == KB_TSEC_FW_EMU_COMPAT)
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
{
|
||||
u32 start = get_tmr_us();
|
||||
u32 k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
|
||||
u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
|
||||
u32 timeout = get_tmr_us() + 125000;
|
||||
u32 key[16] = {0};
|
||||
u32 kidx = 0;
|
||||
|
||||
|
@ -198,21 +216,21 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
{
|
||||
smmu_flush_all();
|
||||
|
||||
if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4])
|
||||
if (k != se[SE_CRYPTO_KEYTABLE_DATA_REG / 4])
|
||||
{
|
||||
k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
|
||||
k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
|
||||
key[kidx++] = k;
|
||||
}
|
||||
|
||||
// Failsafe.
|
||||
if ((u32)get_tmr_us() - start > 125000)
|
||||
if ((u32)get_tmr_us() > timeout)
|
||||
break;
|
||||
}
|
||||
|
||||
if (kidx != 8)
|
||||
{
|
||||
res = -6;
|
||||
smmu_deinit_for_tsec();
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
|
@ -223,12 +241,12 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
memcpy(tsec_keys, &key, 0x20);
|
||||
memcpy(tsec_ctxt->pkg1, iram, 0x30000);
|
||||
|
||||
smmu_deinit_for_tsec();
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
// for (int i = 0; i < kidx; i++)
|
||||
// gfx_printf("key %08X\n", key[i]);
|
||||
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
|
||||
|
||||
// u32 errst = MC(MC_ERR_STATUS);
|
||||
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
|
||||
|
@ -244,14 +262,18 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
res = -3;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!TSEC(TSEC_STATUS))
|
||||
while (!TSEC(TSEC_MAILBOX1))
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = -4;
|
||||
goto out_free;
|
||||
}
|
||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
||||
}
|
||||
|
||||
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
|
||||
{
|
||||
res = -5;
|
||||
goto out_free;
|
||||
|
@ -260,23 +282,22 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
// Fetch result.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
|
||||
u32 buf[4];
|
||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
|
||||
memcpy(tsec_keys, &buf, 0x10);
|
||||
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
out_free:;
|
||||
out_free:
|
||||
free(fwbuf);
|
||||
|
||||
out:;
|
||||
|
||||
out:
|
||||
// Disable clocks.
|
||||
clock_disable_kfuse();
|
||||
clock_disable_sor1();
|
||||
|
@ -284,7 +305,12 @@ out:;
|
|||
clock_disable_sor_safe();
|
||||
clock_disable_tsec();
|
||||
bpmp_mmu_enable();
|
||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
// Re-enable AHB aperture.
|
||||
mc_enable_ahb_redirect();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -20,15 +20,23 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
enum tsec_fw_type
|
||||
{
|
||||
// Retail Hovi Keygen.
|
||||
TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
|
||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
|
||||
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
|
||||
};
|
||||
|
||||
typedef struct _tsec_ctxt_t
|
||||
{
|
||||
void *fw;
|
||||
u32 size;
|
||||
u32 type;
|
||||
void *pkg1;
|
||||
u32 pkg11_off;
|
||||
u32 secmon_base;
|
||||
} tsec_ctxt_t;
|
||||
|
||||
int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt);
|
||||
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,8 +17,8 @@
|
|||
#ifndef _TSEC_T210_H_
|
||||
#define _TSEC_T210_H_
|
||||
|
||||
#define TSEC_BOOTKEYVER 0x1040
|
||||
#define TSEC_STATUS 0x1044
|
||||
#define TSEC_MAILBOX0 0x1040
|
||||
#define TSEC_MAILBOX1 0x1044
|
||||
#define TSEC_ITFEN 0x1048
|
||||
#define TSEC_ITFEN_CTXEN BIT(0)
|
||||
#define TSEC_ITFEN_MTHDEN BIT(1)
|
||||
|
|
172
bdk/soc/actmon.c
Normal file
172
bdk/soc/actmon.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Activity Monitor driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "actmon.h"
|
||||
#include "clock.h"
|
||||
#include "t210.h"
|
||||
|
||||
/* Global registers */
|
||||
#define ACTMON_GLB_STATUS 0x0
|
||||
#define ACTMON_MCCPU_MON_ACT BIT(8)
|
||||
#define ACTMON_MCALL_MON_ACT BIT(9)
|
||||
#define ACTMON_CPU_FREQ_MON_ACT BIT(10)
|
||||
#define ACTMON_APB_MON_ACT BIT(12)
|
||||
#define ACTMON_AHB_MON_ACT BIT(13)
|
||||
#define ACTMON_BPMP_MON_ACT BIT(14)
|
||||
#define ACTMON_CPU_MON_ACT BIT(15)
|
||||
#define ACTMON_MCCPU_INTR BIT(25)
|
||||
#define ACTMON_MCALL_INTR BIT(26)
|
||||
#define ACTMON_CPU_FREQ_INTR BIT(27)
|
||||
#define ACTMON_APB_INTR BIT(28)
|
||||
#define ACTMON_AHB_INTR BIT(29)
|
||||
#define ACTMON_BPMP_INTR BIT(30)
|
||||
#define ACTMON_CPU_INTR BIT(31)
|
||||
#define ACTMON_GLB_PERIOD_CTRL 0x4
|
||||
#define ACTMON_GLB_PERIOD_USEC BIT(8)
|
||||
#define ACTMON_GLB_PERIOD_SAMPLE(n) (((n) - 1) & 0xFF)
|
||||
|
||||
/* Device Registers */
|
||||
#define ACTMON_DEV_BASE ACTMON_BASE + 0x80
|
||||
#define ACTMON_DEV_SIZE 0x40
|
||||
/* CTRL */
|
||||
#define ACTMON_DEV_CTRL_K_VAL(k) (((k) & 7) << 10)
|
||||
#define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18)
|
||||
#define ACTMON_DEV_CTRL_AT_END_EN BIT(19)
|
||||
#define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20)
|
||||
#define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21)
|
||||
#define ACTMON_DEV_CTRL_WHEN_OVERFLOW_EN BIT(22)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM(n) (((n) & 7) << 23)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM(n) (((n) & 7) << 26)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29)
|
||||
#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30)
|
||||
#define ACTMON_DEV_CTRL_ENB BIT(31)
|
||||
/* INTR_STATUS */
|
||||
#define ACTMON_DEV_ISTS_AVG_ABOVE_WMARK BIT(24)
|
||||
#define ACTMON_DEV_ISTS_AVG_BELOW_WMARK BIT(25)
|
||||
#define ACTMON_DEV_ISTS_WHEN_OVERFLOW BIT(26)
|
||||
#define ACTMON_DEV_ISTS_AT_END BIT(29)
|
||||
#define ACTMON_DEV_ISTS_CONSECUTIVE_LOWER BIT(30)
|
||||
#define ACTMON_DEV_ISTS_CONSECUTIVE_UPPER BIT(31)
|
||||
|
||||
/* Histogram Registers */
|
||||
#define ACTMON_HISTOGRAM_CONFIG 0x300
|
||||
#define ACTMON_HIST_CFG_ACTIVE BIT(0)
|
||||
#define ACTMON_HIST_CFG_LINEAR_MODE BIT(1)
|
||||
#define ACTMON_HIST_CFG_NO_UNDERFLOW_BUCKET BIT(2)
|
||||
#define ACTMON_HIST_CFG_STALL_ON_SINGLE_SATURATE BIT(3)
|
||||
#define ACTMON_HIST_CFG_SHIFT(s) (((s) & 0x1F) << 4)
|
||||
#define ACTMON_HIST_CFG_SOURCE(s) (((s) & 0xF) << 12)
|
||||
#define ACTMON_HISTOGRAM_CTRL 0x304
|
||||
#define ACTMON_HIST_CTRL_CLEAR_ALL BIT(0)
|
||||
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
|
||||
#define ACTMON_HISTOGRAM_DATA_NUM 32
|
||||
|
||||
#define ACTMON_FREQ 19200000
|
||||
#define ACTMON_PERIOD_MS 20
|
||||
#define DEV_COUNT_WEIGHT 5
|
||||
|
||||
typedef struct _actmon_dev_reg_t
|
||||
{
|
||||
vu32 ctrl;
|
||||
vu32 upper_wnark;
|
||||
vu32 lower_wmark;
|
||||
vu32 init_avg;
|
||||
vu32 avg_upper_wmark;
|
||||
vu32 avg_lower_wmark;
|
||||
vu32 count_weight;
|
||||
vu32 count;
|
||||
vu32 avg_count;
|
||||
vu32 intr_status;
|
||||
vu32 ctrl2;
|
||||
vu32 rsvd[5];
|
||||
} actmon_dev_reg_t;
|
||||
|
||||
void actmon_hist_enable(actmon_hist_src_t src)
|
||||
{
|
||||
ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
|
||||
ACTMON(ACTMON_HISTOGRAM_CTRL) = ACTMON_HIST_CTRL_CLEAR_ALL;
|
||||
}
|
||||
|
||||
void actmon_hist_disable()
|
||||
{
|
||||
ACTMON(ACTMON_HISTOGRAM_CONFIG) = 0;
|
||||
}
|
||||
|
||||
void actmon_hist_get(u32 *histogram)
|
||||
{
|
||||
if (histogram)
|
||||
{
|
||||
for (u32 i = 0; i < ACTMON_HISTOGRAM_DATA_NUM; i++)
|
||||
histogram[i] = ACTMON(ACTMON_HISTOGRAM_DATA_BASE + i * sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
void actmon_dev_enable(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
|
||||
regs->count_weight = DEV_COUNT_WEIGHT;
|
||||
|
||||
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
|
||||
}
|
||||
|
||||
void actmon_dev_disable(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
regs->ctrl = 0;
|
||||
}
|
||||
|
||||
u32 actmon_dev_get_load(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
// Get load-based sampling. 1 decimal point precision.
|
||||
u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
u32 actmon_dev_get_load_avg(actmon_dev_t dev)
|
||||
{
|
||||
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
|
||||
|
||||
// Get load-based sampling. 1 decimal point precision.
|
||||
u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
|
||||
|
||||
return avg_load;
|
||||
}
|
||||
|
||||
void atmon_dev_all_disable()
|
||||
{
|
||||
// TODO: do a global reset?
|
||||
}
|
||||
|
||||
void actmon_init()
|
||||
{
|
||||
clock_enable_actmon();
|
||||
|
||||
// Set period.
|
||||
ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
|
||||
}
|
||||
|
||||
void actmon_end()
|
||||
{
|
||||
clock_disable_actmon();
|
||||
}
|
62
bdk/soc/actmon.h
Normal file
62
bdk/soc/actmon.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Activity Monitor driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ACTMON_H_
|
||||
#define __ACTMON_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef enum _actmon_dev_t
|
||||
{
|
||||
ACTMON_DEV_CPU,
|
||||
ACTMON_DEV_BPMP,
|
||||
ACTMON_DEV_AHB,
|
||||
ACTMON_DEV_APB,
|
||||
ACTMON_DEV_CPU_FREQ,
|
||||
ACTMON_DEV_MC_ALL,
|
||||
ACTMON_DEV_MC_CPU,
|
||||
|
||||
ACTMON_DEV_NUM,
|
||||
} actmon_dev_t;
|
||||
|
||||
typedef enum _actmon_hist_src_t
|
||||
{
|
||||
ACTMON_HIST_SRC_NONE = 0,
|
||||
ACTMON_HIST_SRC_AHB = 1,
|
||||
ACTMON_HIST_SRC_APB = 2,
|
||||
ACTMON_HIST_SRC_BPMP = 3,
|
||||
ACTMON_HIST_SRC_CPU = 4,
|
||||
ACTMON_HIST_SRC_MC_ALL = 5,
|
||||
ACTMON_HIST_SRC_MC_CPU = 6,
|
||||
ACTMON_HIST_SRC_CPU_FREQ = 7,
|
||||
ACTMON_HIST_SRC_NA = 8,
|
||||
ACTMON_HIST_SRC_APB_MMIO = 9,
|
||||
} actmon_hist_src_t;
|
||||
|
||||
void actmon_hist_enable(actmon_hist_src_t src);
|
||||
void actmon_hist_disable();
|
||||
void actmon_hist_get(u32 *histogram);
|
||||
void actmon_dev_enable(actmon_dev_t dev);
|
||||
void actmon_dev_disable(actmon_dev_t dev);
|
||||
u32 actmon_dev_get_load(actmon_dev_t dev);
|
||||
u32 actmon_dev_get_load_avg(actmon_dev_t dev);
|
||||
void atmon_dev_all_disable();
|
||||
void actmon_init();
|
||||
void actmon_end();
|
||||
|
||||
#endif
|
104
bdk/soc/bpmp.c
104
bdk/soc/bpmp.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,9 +18,9 @@
|
|||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <memory_map.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define BPMP_MMU_CACHE_LINE_SIZE 0x20
|
||||
|
||||
|
@ -118,7 +118,7 @@
|
|||
#define MMU_EN_READ BIT(2)
|
||||
#define MMU_EN_WRITE BIT(3)
|
||||
|
||||
bpmp_mmu_entry_t mmu_entries[] =
|
||||
static const bpmp_mmu_entry_t mmu_entries[] =
|
||||
{
|
||||
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
||||
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
||||
|
@ -134,13 +134,13 @@ void bpmp_mmu_maintenance(u32 op, bool force)
|
|||
// This is a blocking operation.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;
|
||||
|
||||
while(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
while (!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
|
||||
}
|
||||
|
||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
|
||||
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply)
|
||||
{
|
||||
if (idx > 31)
|
||||
return;
|
||||
|
@ -150,8 +150,8 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
|
|||
if (entry->enable)
|
||||
{
|
||||
mmu_entry->start_addr = ALIGN(entry->start_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx);
|
||||
|
||||
|
@ -166,9 +166,9 @@ void bpmp_mmu_enable()
|
|||
return;
|
||||
|
||||
// Init BPMP MMU.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
|
||||
// Init BPMP MMU entries.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;
|
||||
|
@ -200,36 +200,70 @@ void bpmp_mmu_disable()
|
|||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CLK_RST_CONTROLLER_SCLK_BURST_POLICY:
|
||||
* 0 = CLKM
|
||||
* 1 = PLLC_OUT1
|
||||
* 2 = PLLC4_OUT3
|
||||
* 3 = PLLP_OUT0
|
||||
* 4 = PLLP_OUT2
|
||||
* 5 = PLLC4_OUT1
|
||||
* 6 = CLK_S
|
||||
* 7 = PLLC4_OUT2
|
||||
*/
|
||||
|
||||
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
|
||||
|
||||
void bpmp_clk_rate_relaxed(bool enable)
|
||||
{
|
||||
// This is a glitch-free way to reduce the SCLK timings.
|
||||
if (enable)
|
||||
{
|
||||
// Restore to PLLP source during PLLC configuration.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT.
|
||||
usleep(100); // Wait a bit for clock source change.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
||||
}
|
||||
else if (bpmp_fid_current)
|
||||
{
|
||||
// Restore to PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 and CLKM for idle.
|
||||
usleep(100); // Wait a bit for clock source change.
|
||||
}
|
||||
}
|
||||
|
||||
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
|
||||
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
||||
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
||||
const u8 pll_divn[] = {
|
||||
// APB clock max is supposed to be 204 MHz though.
|
||||
static const u8 pll_divn[] = {
|
||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
// Do not use for public releases!
|
||||
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||
};
|
||||
|
||||
bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
|
||||
|
||||
void bpmp_clk_rate_get()
|
||||
{
|
||||
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
||||
|
||||
if (clk_src_is_pllp)
|
||||
bpmp_clock_set = BPMP_CLK_NORMAL;
|
||||
bpmp_fid_current = BPMP_CLK_NORMAL;
|
||||
else
|
||||
{
|
||||
bpmp_clock_set = BPMP_CLK_HIGH_BOOST;
|
||||
bpmp_fid_current = BPMP_CLK_HIGH_BOOST;
|
||||
|
||||
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||
for (u32 i = 1; i < sizeof(pll_divn); i++)
|
||||
{
|
||||
if (pll_divn[i] == pll_divn_curr)
|
||||
{
|
||||
bpmp_clock_set = i;
|
||||
bpmp_fid_current = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -241,35 +275,37 @@ void bpmp_clk_rate_set(bpmp_freq_t fid)
|
|||
if (fid > (BPMP_CLK_MAX - 1))
|
||||
fid = BPMP_CLK_MAX - 1;
|
||||
|
||||
if (bpmp_clock_set == fid)
|
||||
if (bpmp_fid_current == fid)
|
||||
return;
|
||||
|
||||
bpmp_fid_current = fid;
|
||||
|
||||
if (fid)
|
||||
{
|
||||
if (bpmp_clock_set)
|
||||
{
|
||||
// Restore to PLLP source during PLLC4 configuration.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
|
||||
msleep(1); // Wait a bit for clock source change.
|
||||
}
|
||||
// Use default SCLK / HCLK / PCLK clocks.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
// Configure and enable PLLC.
|
||||
clock_enable_pllc(pll_divn[fid]);
|
||||
|
||||
// Set SCLK / HCLK / PCLK.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 for active and CLKM for idle.
|
||||
// Set new source and SCLK / HCLK / PCLK dividers.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT for active and CLKM for idle.
|
||||
msleep(1); // Wait a bit for clock source change.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
||||
// Use default SCLK / HCLK / PCLK clocks.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
// Disable PLLC to save power.
|
||||
clock_disable_pllc();
|
||||
}
|
||||
bpmp_clock_set = fid;
|
||||
}
|
||||
|
||||
// State is reset to RUN on any clock or source set via SW.
|
||||
void bpmp_state_set(bpmp_state_t state)
|
||||
{
|
||||
u32 cfg = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & ~0xF0000000u;
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = cfg | (state << 28u);
|
||||
}
|
||||
|
||||
// The following functions halt BPMP to reduce power while sleeping.
|
||||
|
@ -281,10 +317,10 @@ void bpmp_usleep(u32 us)
|
|||
// Each iteration takes 1us.
|
||||
while (us)
|
||||
{
|
||||
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us;
|
||||
delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
|
||||
us -= delay;
|
||||
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay;
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,14 +331,14 @@ void bpmp_msleep(u32 ms)
|
|||
// Iteration time is variable. ~200 - 1000us.
|
||||
while (ms)
|
||||
{
|
||||
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms;
|
||||
delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
|
||||
ms -= delay;
|
||||
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay;
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
|
||||
}
|
||||
}
|
||||
|
||||
void bpmp_halt()
|
||||
{
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG;
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -47,20 +47,35 @@ typedef enum
|
|||
{
|
||||
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
||||
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
|
||||
BPMP_CLK_HIGH2_BOOST, // 563MHz 38% - 141MHz APB.
|
||||
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_MAX
|
||||
} bpmp_freq_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BPMP_STATE_STANDBY = 0, // 32KHz.
|
||||
BPMP_STATE_IDLE = 1,
|
||||
BPMP_STATE_RUN = 2,
|
||||
|
||||
BPMP_STATE_IRQ = BIT(2),
|
||||
BPMP_STATE_FIQ = BIT(3),
|
||||
} bpmp_state_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
||||
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply);
|
||||
void bpmp_mmu_enable();
|
||||
void bpmp_mmu_disable();
|
||||
void bpmp_clk_rate_relaxed(bool enable);
|
||||
void bpmp_clk_rate_get();
|
||||
void bpmp_clk_rate_set(bpmp_freq_t fid);
|
||||
void bpmp_state_set(bpmp_state_t state);
|
||||
void bpmp_usleep(u32 us);
|
||||
void bpmp_msleep(u32 ms);
|
||||
void bpmp_halt();
|
||||
|
|
147
bdk/soc/ccplex.c
147
bdk/soc/ccplex.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,8 +15,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/clock.h>
|
||||
|
@ -27,96 +27,139 @@
|
|||
#include <power/max77812.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void _ccplex_enable_power_t210()
|
||||
{
|
||||
u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO); // Get current pinmuxing
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & ~BIT(5)); // Disable GPIO5 pinmuxing.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
|
||||
#define CCPLEX_FLOWCTRL_POWERGATING 0
|
||||
|
||||
// Enable cores power.
|
||||
static void _ccplex_enable_power_t210()
|
||||
{
|
||||
// Configure GPIO5 and enable output in order to power CPU pmic.
|
||||
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Configure CPU pmic.
|
||||
// 1-3.x: MAX77621_NFSR_ENABLE.
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,
|
||||
MAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE | MAX77621_RAMP_12mV_PER_US);
|
||||
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
|
||||
MAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL);
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
|
||||
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
|
||||
|
||||
// Set voltage and enable cluster power.
|
||||
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
|
||||
max7762x_regulator_enable(REGULATOR_CPU0, true);
|
||||
}
|
||||
|
||||
void _ccplex_enable_power_t210b01()
|
||||
static void _ccplex_enable_power_t210b01()
|
||||
{
|
||||
u8 pmic_cpu_addr = !(FUSE(FUSE_RESERVED_ODM28) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
|
||||
u8 tmp = i2c_recv_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL);
|
||||
i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL, tmp | MAX77812_EN_CTRL_EN_M4);
|
||||
i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_M4_VOUT, MAX77812_M4_VOUT_0_80V);
|
||||
// Set voltage and enable cluster power.
|
||||
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
|
||||
max7762x_regulator_enable(REGULATOR_CPU1, true);
|
||||
}
|
||||
|
||||
void ccplex_boot_cpu0(u32 entry)
|
||||
static void _ccplex_disable_power()
|
||||
{
|
||||
// Disable cluster power.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
{
|
||||
max7762x_regulator_enable(REGULATOR_CPU0, false);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
|
||||
}
|
||||
else
|
||||
max7762x_regulator_enable(REGULATOR_CPU1, false);
|
||||
}
|
||||
|
||||
void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||
{
|
||||
// Set ACTIVE_CLUSER to FAST.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
_ccplex_enable_power_t210();
|
||||
else
|
||||
_ccplex_enable_power_t210b01();
|
||||
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE.
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7; // Disable IDDQ.
|
||||
usleep(2);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;
|
||||
}
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))
|
||||
;
|
||||
clock_enable_pllx();
|
||||
|
||||
// Configure MSELECT source and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & ~BIT(CLK_V_MSELECT)) | BIT(CLK_V_MSELECT);
|
||||
// Configure MSELECT source and enable clock to 102MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Configure initial CPU clock frequency and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
// CAR2PMC_CPU_ACK_WIDTH should be set to 0.
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||
|
||||
// Enable CPU rail.
|
||||
pmc_enable_partition(0, 1);
|
||||
// Enable CPU main rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, ENABLE);
|
||||
// Enable cluster 0 non-CPU rail.
|
||||
pmc_enable_partition(15, 1);
|
||||
// Enable CE0 rail.
|
||||
pmc_enable_partition(14, 1);
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, ENABLE);
|
||||
// Enable CPU0 rail.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
||||
|
||||
// Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
|
||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & RAM_REPAIR_STS))
|
||||
;
|
||||
|
||||
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
||||
|
||||
// Set reset vector.
|
||||
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
|
||||
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
|
||||
SB(SB_AA64_RESET_HIGH) = 0;
|
||||
|
||||
// Non-secure reset vector write disable.
|
||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
if (lock)
|
||||
{
|
||||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
}
|
||||
|
||||
// Tighten up the security aperture.
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= ~BIT(CLK_V_MSELECT);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
// Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
|
||||
// Clear CPU0 reset.
|
||||
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
|
||||
}
|
||||
|
||||
void ccplex_powergate_cpu0()
|
||||
{
|
||||
#if CCPLEX_FLOWCTRL_POWERGATING
|
||||
// Halt CPU0.
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
|
||||
|
||||
// Powergate cluster via flow control without waiting for WFI.
|
||||
FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
|
||||
|
||||
// Wait for the rail power off to finish.
|
||||
while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
|
||||
|
||||
// Set CPU0 to waitevent.
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
|
||||
#endif
|
||||
|
||||
// Set CPU0 POR and CORE, CX0, L2, and DBG reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
|
||||
// Set NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
|
||||
// Set MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Disable CE0.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
// Disable cluster 0 non-CPU.
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
|
||||
// Disable CPU rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
|
||||
|
||||
clock_disable_coresight();
|
||||
|
||||
// Clear out MSELECT and CPU clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
|
||||
|
||||
_ccplex_disable_power();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
void ccplex_boot_cpu0(u32 entry);
|
||||
void ccplex_boot_cpu0(u32 entry, bool lock);
|
||||
void ccplex_powergate_cpu0();
|
||||
|
||||
#endif
|
||||
|
|
503
bdk/soc/clock.c
503
bdk/soc/clock.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,75 +15,113 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
/* clock_t: reset, enable, source, index, clk_src, clk_div */
|
||||
typedef struct _clock_osc_t
|
||||
{
|
||||
u32 freq;
|
||||
u16 min;
|
||||
u16 max;
|
||||
} clock_osc_t;
|
||||
|
||||
static const clock_t _clock_uart[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
|
||||
static const clock_osc_t _clock_osc_cnt[] = {
|
||||
{ 12000, 706, 757 },
|
||||
{ 13000, 766, 820 },
|
||||
{ 16800, 991, 1059 },
|
||||
{ 19200, 1133, 1210 },
|
||||
{ 26000, 1535, 1638 },
|
||||
{ 38400, 2268, 2418 },
|
||||
{ 48000, 2836, 3023 }
|
||||
};
|
||||
|
||||
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clk_rst_t _clock_uart[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
static const clock_t _clock_i2c[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
||||
static const clk_rst_t _clock_i2c[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0
|
||||
static clk_rst_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408MHz. Default: 408MHz. Max: 627.2 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408MHz.
|
||||
};
|
||||
static clk_rst_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204MHz. Max: 408MHz.
|
||||
};
|
||||
static clk_rst_t _clock_nvdec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2MHz.
|
||||
};
|
||||
static clk_rst_t _clock_nvjpg = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clk_rst_t _clock_vic = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204MHz.
|
||||
};
|
||||
static clk_rst_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136MHz.
|
||||
};
|
||||
static clk_rst_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
|
||||
};
|
||||
static clk_rst_t _clock_apbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204MHz.
|
||||
};
|
||||
static clk_rst_t _clock_ahbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_actmon = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2MHz.
|
||||
};
|
||||
static clk_rst_t _clock_extperiph1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_extperiph2 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0MHz
|
||||
};
|
||||
|
||||
static clock_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3
|
||||
};
|
||||
static clock_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2
|
||||
};
|
||||
static clock_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE, CLK_X_SOR0, 0, 0
|
||||
};
|
||||
static clock_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2
|
||||
};
|
||||
static clock_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
};
|
||||
static clock_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4
|
||||
};
|
||||
|
||||
static clock_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. Stock PLLP / 54: 7.55MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
void clock_enable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
|
@ -91,7 +129,7 @@ void clock_enable(const clock_t *clk)
|
|||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
// Configure clock source if required.
|
||||
if (clk->source)
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
usleep(2);
|
||||
|
@ -100,7 +138,7 @@ void clock_enable(const clock_t *clk)
|
|||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||
}
|
||||
|
||||
void clock_disable(const clock_t *clk)
|
||||
void clock_disable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
|
@ -116,7 +154,13 @@ void clock_enable_fuse(bool enable)
|
|||
|
||||
void clock_enable_uart(u32 idx)
|
||||
{
|
||||
// Ease the stress to APB.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
clock_enable(&_clock_uart[idx]);
|
||||
|
||||
// Restore OC.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
void clock_disable_uart(u32 idx)
|
||||
|
@ -130,11 +174,13 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
|
|||
{
|
||||
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||
|
||||
if (baud == 1000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
|
||||
if (baud == 3000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
|
||||
else if (baud == 1000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
|
||||
else
|
||||
{
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -186,6 +232,42 @@ void clock_disable_tsec()
|
|||
clock_disable(&_clock_tsec);
|
||||
}
|
||||
|
||||
void clock_enable_nvdec()
|
||||
{
|
||||
clock_enable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_disable_nvdec()
|
||||
{
|
||||
clock_disable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_enable_nvjpg()
|
||||
{
|
||||
clock_enable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_disable_nvjpg()
|
||||
{
|
||||
clock_disable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_enable_vic()
|
||||
{
|
||||
// Ease the stress to APB.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
clock_enable(&_clock_vic);
|
||||
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
void clock_disable_vic()
|
||||
{
|
||||
clock_disable(&_clock_vic);
|
||||
}
|
||||
|
||||
void clock_enable_sor_safe()
|
||||
{
|
||||
clock_enable(&_clock_sor_safe);
|
||||
|
@ -218,13 +300,13 @@ void clock_disable_sor1()
|
|||
|
||||
void clock_enable_kfuse()
|
||||
{
|
||||
u32 kfuse_clk_unmask = ~BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= kfuse_clk_unmask;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
|
||||
usleep(10);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= kfuse_clk_unmask;
|
||||
usleep(20);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_KFUSE);
|
||||
usleep(10); // Wait 10s to prevent glitching.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
usleep(20); // Wait 20s fo kfuse hw to init.
|
||||
}
|
||||
|
||||
void clock_disable_kfuse()
|
||||
|
@ -254,7 +336,13 @@ void clock_disable_coresight()
|
|||
|
||||
void clock_enable_pwm()
|
||||
{
|
||||
// Ease the stress to APB.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
clock_enable(&_clock_pwm);
|
||||
|
||||
// Restore OC.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
void clock_disable_pwm()
|
||||
|
@ -262,6 +350,110 @@ void clock_disable_pwm()
|
|||
clock_disable(&_clock_pwm);
|
||||
}
|
||||
|
||||
void clock_enable_apbdma()
|
||||
{
|
||||
clock_enable(&_clock_apbdma);
|
||||
}
|
||||
|
||||
void clock_disable_apbdma()
|
||||
{
|
||||
clock_disable(&_clock_apbdma);
|
||||
}
|
||||
|
||||
void clock_enable_ahbdma()
|
||||
{
|
||||
clock_enable(&_clock_ahbdma);
|
||||
}
|
||||
|
||||
void clock_disable_ahbdma()
|
||||
{
|
||||
clock_disable(&_clock_ahbdma);
|
||||
}
|
||||
|
||||
void clock_enable_actmon()
|
||||
{
|
||||
clock_enable(&_clock_actmon);
|
||||
}
|
||||
|
||||
void clock_disable_actmon()
|
||||
{
|
||||
clock_disable(&_clock_actmon);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph1()
|
||||
{
|
||||
clock_enable(&_clock_extperiph1);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph1()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph1);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph2()
|
||||
{
|
||||
clock_enable(&_clock_extperiph2);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph2()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph2);
|
||||
}
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
||||
{
|
||||
u32 plld_div = (divp << 20) | (divn << 11) | 1;
|
||||
|
||||
// N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
|
||||
u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
|
||||
if (lowpower && tegra_t210)
|
||||
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||
|
||||
// Set DISP1 clock source.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
|
||||
|
||||
// Set dividers and enable PLLD.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||
|
||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||
}
|
||||
|
||||
void clock_enable_pllx()
|
||||
{
|
||||
// Configure and enable PLLX if disabled.
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE.
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
||||
usleep(2);
|
||||
|
||||
// Set div configuration.
|
||||
const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz.
|
||||
|
||||
// Bypass dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | pllx_div_cfg;
|
||||
// Disable bypass
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg;
|
||||
// Set PLLX_LOCK_ENABLE.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN;
|
||||
// Enable PLLX.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | pllx_div_cfg;
|
||||
}
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK))
|
||||
;
|
||||
}
|
||||
|
||||
void clock_enable_pllc(u32 divn)
|
||||
{
|
||||
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||
|
@ -272,7 +464,7 @@ void clock_enable_pllc(u32 divn)
|
|||
|
||||
// Take PLLC out of reset and set basic misc parameters.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
|
@ -289,21 +481,21 @@ void clock_enable_pllc(u32 divn)
|
|||
;
|
||||
|
||||
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = BIT(8);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 1 << 8;
|
||||
|
||||
// Enable PLLC_OUT1 and bring it out of reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR;
|
||||
msleep(1); // Wait a bit for PLL to stabilize.
|
||||
}
|
||||
|
||||
void clock_disable_pllc()
|
||||
{
|
||||
// Disable PLLC and PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~(PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_REF_DIS;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) |= PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
|
@ -328,7 +520,7 @@ static void _clock_enable_pllc4(u32 mask)
|
|||
usleep(10);
|
||||
|
||||
// Set PLLC4 dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||
|
||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
||||
|
@ -366,9 +558,9 @@ void clock_enable_pllu()
|
|||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
|
||||
u32 timeout = get_tmr_us() + 1300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
||||
if ((u32)TMR(TIMERUS_CNTR_1US) > timeout)
|
||||
if (get_tmr_us() > timeout)
|
||||
break;
|
||||
usleep(10);
|
||||
|
||||
|
@ -378,9 +570,9 @@ void clock_enable_pllu()
|
|||
|
||||
void clock_disable_pllu()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~BIT(30); // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~BIT(29); // Enable reference clock.
|
||||
}
|
||||
|
||||
void clock_enable_utmipll()
|
||||
|
@ -509,7 +701,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
clock_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
|
@ -524,6 +716,7 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
|||
|
||||
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
|
@ -539,81 +732,90 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
|||
{
|
||||
case 25000:
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
divisor = CLK_SRC_DIV(16.5);
|
||||
break;
|
||||
|
||||
case 26000:
|
||||
*pclock = 25500;
|
||||
divisor = 30; // 16 div.
|
||||
break;
|
||||
case 40800:
|
||||
*pclock = 40800;
|
||||
divisor = 18; // 10 div.
|
||||
divisor = CLK_SRC_DIV(16);
|
||||
break;
|
||||
|
||||
case 50000:
|
||||
*pclock = 48000;
|
||||
divisor = 15; // 8.5 div.
|
||||
divisor = CLK_SRC_DIV(8.5);
|
||||
break;
|
||||
|
||||
case 52000:
|
||||
*pclock = 51000;
|
||||
divisor = 14; // 8 div.
|
||||
divisor = CLK_SRC_DIV(8);
|
||||
break;
|
||||
|
||||
case 82000:
|
||||
*pclock = 81600;
|
||||
divisor = CLK_SRC_DIV(5);
|
||||
break;
|
||||
|
||||
case 100000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
*pclock = 99840;
|
||||
divisor = 2; // 2 div.
|
||||
divisor = CLK_SRC_DIV(2);
|
||||
break;
|
||||
|
||||
case 164000:
|
||||
*pclock = 163200;
|
||||
divisor = 3; // 2.5 div.
|
||||
divisor = CLK_SRC_DIV(2.5);
|
||||
break;
|
||||
case 200000: // 240MHz evo+.
|
||||
|
||||
case 200000:
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
|
||||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
divisor = 0; // 1 div.
|
||||
divisor = CLK_SRC_DIV(1);
|
||||
break;
|
||||
default:
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case 400000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
|
||||
*pclock = 399360;
|
||||
divisor = CLK_SRC_DIV(2.5);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[id].clock = val;
|
||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
||||
|
||||
// Enable PLLC4 if in use by any SDMMC.
|
||||
if (source)
|
||||
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||
_clock_enable_pllc4(BIT(id));
|
||||
|
||||
// Set SDMMC legacy timeout clock.
|
||||
_clock_sdmmc_config_legacy_tm();
|
||||
|
||||
// Set SDMMC clock.
|
||||
u32 src_div = (source << 29u) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -643,54 +845,71 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
|||
// Get Card clock divisor.
|
||||
switch (type)
|
||||
{
|
||||
case SDHCI_TIMING_MMC_ID: // Actual IO Freq: 380.59 KHz.
|
||||
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||
*pclock = 26000;
|
||||
*pdivisor = 66;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_LS26:
|
||||
*pclock = 26000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS52:
|
||||
*pclock = 52000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
*pclock = 200000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_SD_ID: // Actual IO Freq: 380.43 KHz.
|
||||
|
||||
case SDHCI_TIMING_SD_ID: // Actual card clock: 386.38 KHz.
|
||||
*pclock = 25000;
|
||||
*pdivisor = 64;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_DS12:
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
*pclock = 25000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_HS25:
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
*pclock = 50000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
*pclock = 100000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
*pclock = 164000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
*pclock = 40800;
|
||||
*pdivisor = 1;
|
||||
|
||||
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||
*pclock = 82000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
|
||||
|
||||
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SDHCI_TIMING_UHS_DDR200: // Actual card clock: 199.68 KHz.
|
||||
*pclock = 400000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -709,7 +928,8 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
|||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + clock - 1) / clock);
|
||||
// Wait 100 cycles for reset and for clocks to stabilize.
|
||||
usleep((100 * 1000 + clock - 1) / clock);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
|
@ -721,3 +941,56 @@ void clock_sdmmc_disable(u32 id)
|
|||
_clock_sdmmc_is_reset(id);
|
||||
_clock_disable_pllc4(BIT(id));
|
||||
}
|
||||
|
||||
u32 clock_get_osc_freq()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_FREQ_DET) = OSC_FREQ_DET_TRIG | (2 - 1); // 2 periods of 32.76KHz window.
|
||||
while (CLOCK(CLK_RST_CONTROLLER_OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY)
|
||||
;
|
||||
u32 cnt = (CLOCK(CLK_RST_CONTROLLER_OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_CNT);
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_FREQ_DET) = 0;
|
||||
|
||||
// Return frequency in KHz.
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_clock_osc_cnt); i++)
|
||||
if (cnt >= _clock_osc_cnt[i].min && cnt <= _clock_osc_cnt[i].max)
|
||||
return _clock_osc_cnt[i].freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 clock_get_dev_freq(clock_pto_id_t id)
|
||||
{
|
||||
const u32 pto_win = 16;
|
||||
const u32 pto_osc = 32768;
|
||||
|
||||
u32 val = ((id & PTO_SRC_SEL_MASK) << PTO_SRC_SEL_SHIFT) | PTO_DIV_SEL_DIV1 | PTO_CLK_ENABLE | (pto_win - 1);
|
||||
CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
|
||||
usleep(2);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val | PTO_CNT_RST;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
|
||||
usleep(2);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
|
||||
usleep(2);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val | PTO_CNT_EN;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
|
||||
usleep((1000000 * pto_win / pto_osc) + 12 + 2);
|
||||
|
||||
while (CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_STATUS) & PTO_CLK_CNT_BUSY)
|
||||
;
|
||||
|
||||
u32 cnt = CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_STATUS) & PTO_CLK_CNT;
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = 0;
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL);
|
||||
usleep(2);
|
||||
|
||||
u32 freq_khz = (u64)cnt * pto_osc / pto_win / 1000;
|
||||
|
||||
return freq_khz;
|
||||
}
|
||||
|
||||
|
|
331
bdk/soc/clock.h
331
bdk/soc/clock.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -35,6 +35,10 @@
|
|||
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
|
||||
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
|
||||
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
|
||||
#define CLK_RST_CONTROLLER_OSC_FREQ_DET 0x58
|
||||
#define CLK_RST_CONTROLLER_OSC_FREQ_DET_STATUS 0x5C
|
||||
#define CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL 0x60
|
||||
#define CLK_RST_CONTROLLER_PTO_CLK_CNT_STATUS 0x64
|
||||
#define CLK_RST_CONTROLLER_PLLC_BASE 0x80
|
||||
#define CLK_RST_CONTROLLER_PLLC_OUT 0x84
|
||||
#define CLK_RST_CONTROLLER_PLLC_MISC 0x88
|
||||
|
@ -43,6 +47,7 @@
|
|||
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
|
||||
#define CLK_RST_CONTROLLER_PLLP_OUTB 0xA8
|
||||
#define CLK_RST_CONTROLLER_PLLA_BASE 0xB0
|
||||
#define CLK_RST_CONTROLLER_PLLA_OUT 0xB4
|
||||
#define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8
|
||||
|
@ -113,7 +118,10 @@
|
|||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_AHUB 0x3D0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
|
@ -142,6 +150,7 @@
|
|||
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
|
||||
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
|
||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||
#define CLK_RST_CONTROLLER_PLLMB_MISC1 0x5EC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
|
||||
|
@ -149,18 +158,31 @@
|
|||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC
|
||||
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE 0x710
|
||||
|
||||
#define CLK_NO_SOURCE 0x0
|
||||
#define CLK_NOT_USED 0x0
|
||||
|
||||
/*! PLL control and status bits */
|
||||
#define PLLX_BASE_LOCK BIT(27)
|
||||
#define PLLX_BASE_REF_DIS BIT(29)
|
||||
#define PLLX_BASE_ENABLE BIT(30)
|
||||
#define PLLX_BASE_BYPASS BIT(31)
|
||||
#define PLLX_MISC_LOCK_EN BIT(18)
|
||||
#define PLLX_MISC3_IDDQ BIT(3)
|
||||
|
||||
#define PLLCX_BASE_LOCK BIT(27)
|
||||
#define PLLCX_BASE_REF_DIS BIT(29)
|
||||
#define PLLCX_BASE_ENABLE BIT(30)
|
||||
#define PLLCX_BASE_BYPASS BIT(31)
|
||||
|
||||
#define PLLA_OUT0_RSTN_CLR BIT(0)
|
||||
#define PLLA_OUT0_CLKEN BIT(1)
|
||||
|
@ -178,6 +200,266 @@
|
|||
|
||||
#define UTMIPLL_LOCK BIT(31)
|
||||
|
||||
/*! Clock source */
|
||||
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
|
||||
|
||||
/*! PTO_CLK_CNT */
|
||||
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
|
||||
#define PTO_REF_CLK_WIN_CFG_16P 0xF
|
||||
#define PTO_CNT_EN BIT(9)
|
||||
#define PTO_CNT_RST BIT(10)
|
||||
#define PTO_CLK_ENABLE BIT(13)
|
||||
#define PTO_SRC_SEL_SHIFT 14
|
||||
#define PTO_SRC_SEL_MASK 0x1FF
|
||||
#define PTO_DIV_SEL_MASK (3 << 23)
|
||||
#define PTO_DIV_SEL_GATED (0 << 23)
|
||||
#define PTO_DIV_SEL_DIV1 (1 << 23)
|
||||
#define PTO_DIV_SEL_DIV2_RISING (2 << 23)
|
||||
#define PTO_DIV_SEL_DIV2_FALLING (3 << 23)
|
||||
#define PTO_DIV_SEL_CPU_EARLY (0 << 23)
|
||||
#define PTO_DIV_SEL_CPU_LATE (1 << 23)
|
||||
|
||||
#define PTO_CLK_CNT_BUSY BIT(31)
|
||||
#define PTO_CLK_CNT 0xFFFFFF
|
||||
|
||||
/*! OSC_FREQ_DET */
|
||||
#define OSC_REF_CLK_WIN_CFG_MASK 0xF
|
||||
#define OSC_FREQ_DET_TRIG BIT(31)
|
||||
|
||||
#define OSC_FREQ_DET_BUSY BIT(31)
|
||||
#define OSC_FREQ_DET_CNT 0xFFFF
|
||||
|
||||
/*! PTO IDs. */
|
||||
typedef enum _clock_pto_id_t
|
||||
{
|
||||
CLK_PTO_PCLK_SYS = 0x06,
|
||||
CLK_PTO_HCLK_SYS = 0x07,
|
||||
CLK_PTO_DMIC1 = 0x08,
|
||||
CLK_PTO_DMIC2 = 0x09,
|
||||
CLK_PTO_HDMI_SLOWCLK_DIV2 = 0x0A,
|
||||
CLK_PTO_JTAG_REG = 0x0B,
|
||||
CLK_PTO_UTMIP_240_A = 0x0C,
|
||||
CLK_PTO_UTMIP_240_B = 0x0D,
|
||||
|
||||
CLK_PTO_CCLK_G = 0x12,
|
||||
CLK_PTO_CCLK_G_DIV2 = 0x13,
|
||||
CLK_PTO_MIPIBIF = 0x14,
|
||||
|
||||
CLK_PTO_SPI1 = 0x17,
|
||||
CLK_PTO_SPI2 = 0x18,
|
||||
CLK_PTO_SPI3 = 0x19,
|
||||
CLK_PTO_SPI4 = 0x1A,
|
||||
CLK_PTO_MAUD = 0x1B,
|
||||
CLK_PTO_SCLK = 0x1C,
|
||||
|
||||
CLK_PTO_SDMMC1 = 0x20,
|
||||
CLK_PTO_SDMMC2 = 0x21,
|
||||
CLK_PTO_SDMMC3 = 0x22,
|
||||
CLK_PTO_SDMMC4 = 0x23,
|
||||
CLK_PTO_EMC = 0x24,
|
||||
|
||||
CLK_PTO_DMIC3 = 0x2A,
|
||||
CLK_PTO_CCLK_LP = 0x2B,
|
||||
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
|
||||
|
||||
CLK_PTO_MSELECT = 0x2F,
|
||||
|
||||
CLK_PTO_VI_SENSOR2 = 0x33,
|
||||
CLK_PTO_VI_SENSOR = 0x34,
|
||||
CLK_PTO_VIC = 0x35,
|
||||
CLK_PTO_VIC_SKIP = 0x36,
|
||||
CLK_PTO_ISP_SKIP = 0x37,
|
||||
CLK_PTO_ISPB_SE2_SKIP = 0x38,
|
||||
CLK_PTO_NVDEC_SKIP = 0x39,
|
||||
CLK_PTO_NVENC_SKIP = 0x3A,
|
||||
CLK_PTO_NVJPG_SKIP = 0x3B,
|
||||
CLK_PTO_TSEC_SKIP = 0x3C,
|
||||
CLK_PTO_TSECB_SKIP = 0x3D,
|
||||
CLK_PTO_SE_SKIP = 0x3E,
|
||||
CLK_PTO_VI_SKIP = 0x3F,
|
||||
|
||||
CLK_PTO_PLLX_OBS = 0x40,
|
||||
CLK_PTO_PLLC_OBS = 0x41,
|
||||
CLK_PTO_PLLM_OBS = 0x42,
|
||||
CLK_PTO_PLLP_OBS = 0x43,
|
||||
CLK_PTO_PLLA_OBS = 0x44,
|
||||
CLK_PTO_PLLMB_OBS = 0x45,
|
||||
CLK_PTO_SATA_OOB = 0x46,
|
||||
|
||||
CLK_PTO_FCPU_DVFS_DIV12_CPU = 0x48,
|
||||
|
||||
CLK_PTO_EQOS_AXI = 0x4C,
|
||||
CLK_PTO_EQOS_PTP_REF = 0x4D,
|
||||
CLK_PTO_EQOS_TX = 0x4E,
|
||||
CLK_PTO_EQOS_RX = 0x4F,
|
||||
|
||||
CLK_PTO_CILAB = 0x52,
|
||||
CLK_PTO_CILCD = 0x53,
|
||||
|
||||
CLK_PTO_CILEF = 0x55,
|
||||
CLK_PTO_PLLA1_PTO_OBS = 0x56,
|
||||
CLK_PTO_PLLC4_PTO_OBS = 0x57,
|
||||
|
||||
CLK_PTO_PLLC2_PTO_OBS = 0x59,
|
||||
CLK_PTO_PLLC3_PTO_OBS = 0x5B,
|
||||
|
||||
CLK_PTO_DSIA_LP = 0x62,
|
||||
CLK_PTO_DSIB_LP = 0x63,
|
||||
CLK_PTO_ISP = 0x64,
|
||||
CLK_PTO_PEX_PAD = 0x65,
|
||||
|
||||
CLK_PTO_MC = 0x6A,
|
||||
|
||||
CLK_PTO_ACTMON = 0x6B,
|
||||
CLK_PTO_CSITE = 0x6C,
|
||||
CLK_PTO_VI_I2C = 0x6D,
|
||||
|
||||
CLK_PTO_HOST1X = 0x6F,
|
||||
|
||||
CLK_PTO_QSPI_2X = 0x71,
|
||||
CLK_PTO_NVDEC = 0x72,
|
||||
CLK_PTO_NVJPG = 0x73,
|
||||
CLK_PTO_SE = 0x74,
|
||||
CLK_PTO_SOC_THERM = 0x75,
|
||||
|
||||
CLK_PTO_TSEC = 0x77,
|
||||
CLK_PTO_TSECB = 0x78,
|
||||
CLK_PTO_VI = 0x79,
|
||||
CLK_PTO_LA = 0x7A,
|
||||
CLK_PTO_SCLK_SKIP = 0x7B,
|
||||
|
||||
CLK_PTO_ADSP_SKIP = 0x7C,
|
||||
CLK_PTO_QSPI = 0x7D,
|
||||
|
||||
CLK_PTO_SDMMC2_SHAPER = 0x7E,
|
||||
CLK_PTO_SDMMC4_SHAPER = 0x7F,
|
||||
CLK_PTO_I2S1 = 0x80,
|
||||
CLK_PTO_I2S2 = 0x81,
|
||||
CLK_PTO_I2S3 = 0x82,
|
||||
CLK_PTO_I2S4 = 0x83,
|
||||
CLK_PTO_I2S5 = 0x84,
|
||||
CLK_PTO_AHUB = 0x85,
|
||||
CLK_PTO_APE = 0x86,
|
||||
|
||||
CLK_PTO_DVFS_SOC = 0x88,
|
||||
CLK_PTO_DVFS_REF = 0x89,
|
||||
CLK_PTO_ADSP_CLK = 0x8A,
|
||||
CLK_PTO_ADSP_DIV2_CLK = 0x8B,
|
||||
|
||||
CLK_PTO_SPDIF_OUT = 0x8F,
|
||||
CLK_PTO_SPDIF_IN = 0x90,
|
||||
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
|
||||
CLK_PTO_SYS2HSIO_SATA_CLK = 0x92,
|
||||
CLK_PTO_PWM = 0x93,
|
||||
CLK_PTO_I2C1 = 0x94,
|
||||
CLK_PTO_I2C2 = 0x95,
|
||||
CLK_PTO_I2C3 = 0x96,
|
||||
CLK_PTO_I2C4 = 0x97,
|
||||
CLK_PTO_I2C5 = 0x98,
|
||||
CLK_PTO_I2C6 = 0x99,
|
||||
CLK_PTO_I2C_SLOW = 0x9A,
|
||||
CLK_PTO_UARTAPE = 0x9B,
|
||||
|
||||
CLK_PTO_EXTPERIPH1 = 0x9D,
|
||||
CLK_PTO_EXTPERIPH2 = 0x9E,
|
||||
CLK_PTO_EXTPERIPH3 = 0x9F,
|
||||
CLK_PTO_ENTROPY = 0xA0,
|
||||
CLK_PTO_UARTA = 0xA1,
|
||||
CLK_PTO_UARTB = 0xA2,
|
||||
CLK_PTO_UARTC = 0xA3,
|
||||
CLK_PTO_UARTD = 0xA4,
|
||||
CLK_PTO_OWR = 0xA5,
|
||||
CLK_PTO_TSENSOR = 0xA6,
|
||||
CLK_PTO_HDA2CODEC_2X = 0xA7,
|
||||
CLK_PTO_HDA = 0xA8,
|
||||
CLK_PTO_EMC_LATENCY = 0xA9,
|
||||
CLK_PTO_EMC_DLL = 0xAA,
|
||||
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
|
||||
CLK_PTO_DBGAPB = 0xAC,
|
||||
|
||||
CLK_PTO_SOR0 = 0xC0,
|
||||
CLK_PTO_SOR1 = 0xC1,
|
||||
CLK_PTO_HDMI = 0xC2,
|
||||
|
||||
CLK_PTO_DISP2 = 0xC4,
|
||||
CLK_PTO_DISP1 = 0xC5,
|
||||
|
||||
CLK_PTO_PLLD_OBS = 0xCA,
|
||||
CLK_PTO_PLLD2_PTO_OBS = 0xCC,
|
||||
CLK_PTO_PLLDP_OBS = 0xCE,
|
||||
CLK_PTO_PLLE_OBS = 0x10A,
|
||||
CLK_PTO_PLLU_OBS = 0x10C,
|
||||
CLK_PTO_PLLREFE_OBS = 0x10E,
|
||||
|
||||
CLK_PTO_XUSB_FALCON = 0x110,
|
||||
CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
|
||||
CLK_PTO_USB_L0_RX = 0x112,
|
||||
CLK_PTO_USB_L3_RX = 0x113,
|
||||
CLK_PTO_USB_RX = 0x114,
|
||||
CLK_PTO_USB3_L0_TXCLKREF = 0x115,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
|
||||
CLK_PTO_PEX_L4_RX = 0x11A,
|
||||
CLK_PTO_PEX_TXCLKREF = 0x11B,
|
||||
CLK_PTO_PEX_TXCLKREF_DIV2 = 0x11C,
|
||||
CLK_PTO_PEX_TXCLKREF2 = 0x11D,
|
||||
CLK_PTO_PEX_L0_RX = 0x11E,
|
||||
CLK_PTO_PEX_L1_RX = 0x11F,
|
||||
CLK_PTO_PEX_L2_RX = 0x120,
|
||||
CLK_PTO_PEX_L3_RX = 0x121,
|
||||
CLK_PTO_SATA_TXCLKREF = 0x122,
|
||||
CLK_PTO_SATA_TXCLKREF_DIV2 = 0x123,
|
||||
CLK_PTO_USB_L5_RX = 0x124,
|
||||
CLK_PTO_SATA_TX = 0x125,
|
||||
CLK_PTO_SATA_L0_RX = 0x126,
|
||||
|
||||
CLK_PTO_USB3_L1_TXCLKREF = 0x129,
|
||||
CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
|
||||
CLK_PTO_USB3_L7_RX = 0x12B,
|
||||
CLK_PTO_USB3_TX = 0x12C,
|
||||
CLK_PTO_UTMIP_PLL_PAD = 0x12D,
|
||||
|
||||
CLK_PTO_XUSB_FS = 0x136,
|
||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
||||
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
||||
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
||||
|
||||
CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
|
||||
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
|
||||
CLK_PTO_USB_L4_RX = 0x13E,
|
||||
CLK_PTO_USB_L6_RX = 0x13F,
|
||||
|
||||
/*
|
||||
* PLL need PTO enabled in MISC registers.
|
||||
* Normal div is 2 so result is multiplied with it.
|
||||
*/
|
||||
CLK_PTO_PLLC_DIV2 = 0x01,
|
||||
CLK_PTO_PLLM_DIV2 = 0x02,
|
||||
CLK_PTO_PLLP_DIV2 = 0x03,
|
||||
CLK_PTO_PLLA_DIV2 = 0x04,
|
||||
CLK_PTO_PLLX_DIV2 = 0x05,
|
||||
|
||||
CLK_PTO_PLLMB_DIV2 = 0x25,
|
||||
|
||||
CLK_PTO_PLLC4_DIV2 = 0x51,
|
||||
|
||||
CLK_PTO_PLLA1_DIV2 = 0x55,
|
||||
CLK_PTO_PLLC2_DIV2 = 0x58,
|
||||
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
||||
|
||||
CLK_PTO_PLLD_DIV2 = 0xCB,
|
||||
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
||||
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
||||
|
||||
CLK_PTO_PLLE_DIV2 = 0x10B,
|
||||
|
||||
CLK_PTO_PLLU_DIV2 = 0x10D,
|
||||
|
||||
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
||||
} clock_pto_id_t;
|
||||
|
||||
/*
|
||||
* CLOCK Peripherals:
|
||||
* L 0 - 31
|
||||
|
@ -216,7 +498,7 @@ enum CLK_L_DEV
|
|||
CLK_L_USBD = 22,
|
||||
CLK_L_ISP = 23,
|
||||
CLK_L_3D = 24, // HIDDEN.
|
||||
//CLK_L_ = 25,
|
||||
CLK_L_IDE = 25, // RESERVED.
|
||||
CLK_L_DISP2 = 26,
|
||||
CLK_L_DISP1 = 27,
|
||||
CLK_L_HOST1X = 28,
|
||||
|
@ -244,11 +526,11 @@ enum CLK_H_DEV
|
|||
CLK_H_SPI3 = 14,
|
||||
CLK_H_I2C5 = 15,
|
||||
CLK_H_DSI = 16,
|
||||
//CLK_H_ = 17,
|
||||
CLK_H_TVO = 17, // RESERVED.
|
||||
CLK_H_HSI = 18, // HIDDEN.
|
||||
CLK_H_HDMI = 19, // HIDDEN.
|
||||
CLK_H_CSI = 20,
|
||||
//CLK_H_ = 21,
|
||||
CLK_H_TVDAC = 21, // RESERVED.
|
||||
CLK_H_I2C2 = 22,
|
||||
CLK_H_UARTC = 23,
|
||||
CLK_H_MIPI_CAL = 24,
|
||||
|
@ -263,14 +545,14 @@ enum CLK_H_DEV
|
|||
|
||||
enum CLK_U_DEV
|
||||
{
|
||||
//CLK_U_ = 0,
|
||||
CLK_U_SPEEDO = 0, // RESERVED.
|
||||
CLK_U_UARTD = 1,
|
||||
CLK_U_UARTE = 2, // HIDDEN.
|
||||
CLK_U_I2C3 = 3,
|
||||
CLK_U_SPI4 = 4,
|
||||
CLK_U_SDMMC3 = 5,
|
||||
CLK_U_PCIE = 6,
|
||||
CLK_U_UNUSED = 7, // RESERVED
|
||||
CLK_U_OWR = 7, // RESERVED.
|
||||
CLK_U_AFI = 8,
|
||||
CLK_U_CSITE = 9,
|
||||
CLK_U_PCIEXCLK = 10, // Only reset.
|
||||
|
@ -442,19 +724,19 @@ enum CLK_Y_DEV
|
|||
};
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clock_t
|
||||
typedef struct _clk_rst_t
|
||||
{
|
||||
u32 reset;
|
||||
u32 enable;
|
||||
u32 source;
|
||||
u16 reset;
|
||||
u16 enable;
|
||||
u16 source;
|
||||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
} clock_t;
|
||||
} clk_rst_t;
|
||||
|
||||
/*! Generic clock enable/disable. */
|
||||
void clock_enable(const clock_t *clk);
|
||||
void clock_disable(const clock_t *clk);
|
||||
void clock_enable(const clk_rst_t *clk);
|
||||
void clock_disable(const clk_rst_t *clk);
|
||||
|
||||
/*! Clock control for specific hardware portions. */
|
||||
void clock_enable_fuse(bool enable);
|
||||
|
@ -469,6 +751,12 @@ void clock_enable_host1x();
|
|||
void clock_disable_host1x();
|
||||
void clock_enable_tsec();
|
||||
void clock_disable_tsec();
|
||||
void clock_enable_nvdec();
|
||||
void clock_disable_nvdec();
|
||||
void clock_enable_nvjpg();
|
||||
void clock_disable_nvjpg();
|
||||
void clock_enable_vic();
|
||||
void clock_disable_vic();
|
||||
void clock_enable_sor_safe();
|
||||
void clock_disable_sor_safe();
|
||||
void clock_enable_sor0();
|
||||
|
@ -483,15 +771,32 @@ void clock_enable_coresight();
|
|||
void clock_disable_coresight();
|
||||
void clock_enable_pwm();
|
||||
void clock_disable_pwm();
|
||||
void clock_enable_apbdma();
|
||||
void clock_disable_apbdma();
|
||||
void clock_enable_ahbdma();
|
||||
void clock_disable_ahbdma();
|
||||
void clock_enable_actmon();
|
||||
void clock_disable_actmon();
|
||||
void clock_enable_extperiph1();
|
||||
void clock_disable_extperiph1();
|
||||
void clock_enable_extperiph2();
|
||||
void clock_disable_extperiph2();
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210);
|
||||
void clock_enable_pllx();
|
||||
void clock_enable_pllc(u32 divn);
|
||||
void clock_disable_pllc();
|
||||
void clock_enable_pllu();
|
||||
void clock_disable_pllu();
|
||||
void clock_enable_utmipll();
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
u32 clock_get_osc_freq();
|
||||
u32 clock_get_dev_freq(clock_pto_id_t id);
|
||||
|
||||
#endif
|
||||
|
|
183
bdk/soc/fuse.c
183
bdk/soc/fuse.c
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/t210.h>
|
||||
|
@ -40,12 +43,19 @@ static const u32 evp_thunk_template[] = {
|
|||
0xe3822001, // ORR R2, R2, #1
|
||||
0xe8bd0003, // LDMFD SP!, {R0,R1}
|
||||
0xe12fff12, // BX R2
|
||||
// idx: 15:
|
||||
0x001007b0, // off_1007EC DCD evp_thunk_template
|
||||
0x001007f8, // off_1007F0 DCD thunk_end
|
||||
0x40004c30, // off_1007F4 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
|
||||
|
||||
static const u32 evp_thunk_func_offsets_t210b01[] = {
|
||||
0x0010022c, // off_100268 DCD evp_thunk_template
|
||||
0x00100174, // off_10026C DCD thunk_end
|
||||
0x40004164, // off_100270 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
|
||||
// treated as 12bit values
|
||||
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
|
||||
|
@ -76,41 +86,89 @@ u32 fuse_read_odm_keygen_rev()
|
|||
return 0;
|
||||
}
|
||||
|
||||
u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
u32 odm4 = fuse_read_odm(4);
|
||||
|
||||
u32 dramid = (odm4 & 0xF8) >> 3;
|
||||
|
||||
// Get extended dram id info.
|
||||
if (!tegra_t210)
|
||||
dramid |= (odm4 & 0x7000) >> 7;
|
||||
|
||||
if (raw_id)
|
||||
return dramid;
|
||||
|
||||
if (tegra_t210)
|
||||
{
|
||||
if (dramid > 7)
|
||||
dramid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dramid > 34)
|
||||
dramid = 8;
|
||||
}
|
||||
|
||||
return dramid;
|
||||
}
|
||||
|
||||
u32 fuse_read_hw_state()
|
||||
{
|
||||
if ((fuse_read_odm(4) & 3) != 3)
|
||||
return FUSE_NX_HW_STATE_PROD;
|
||||
else
|
||||
return FUSE_NX_HW_STATE_DEV;
|
||||
}
|
||||
|
||||
u32 fuse_read_hw_type()
|
||||
{
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
{
|
||||
switch ((fuse_read_odm(4) & 0xF0000) >> 16)
|
||||
{
|
||||
case 1:
|
||||
return FUSE_NX_HW_TYPE_IOWA;
|
||||
case 2:
|
||||
return FUSE_NX_HW_TYPE_HOAG;
|
||||
case 4:
|
||||
return FUSE_NX_HW_TYPE_AULA;
|
||||
case 1:
|
||||
default:
|
||||
return FUSE_NX_HW_TYPE_IOWA;
|
||||
}
|
||||
}
|
||||
|
||||
return FUSE_NX_HW_TYPE_ICOSA;
|
||||
}
|
||||
|
||||
u8 fuse_count_burnt(u32 val)
|
||||
int fuse_set_sbk()
|
||||
{
|
||||
u8 burnt_fuses = 0;
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
if (FUSE(FUSE_PRIVATE_KEY0) != 0xFFFFFFFF)
|
||||
{
|
||||
if ((val >> i) & 1)
|
||||
burnt_fuses++;
|
||||
// Read SBK from fuses.
|
||||
u32 sbk[4] = {
|
||||
FUSE(FUSE_PRIVATE_KEY0),
|
||||
FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2),
|
||||
FUSE(FUSE_PRIVATE_KEY3)
|
||||
};
|
||||
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, SE_KEY_128_SIZE);
|
||||
|
||||
// Lock SBK from being read.
|
||||
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return burnt_fuses;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fuse_wait_idle()
|
||||
{
|
||||
u32 ctrl;
|
||||
do
|
||||
{
|
||||
ctrl = FUSE(FUSE_CTRL);
|
||||
} while (((ctrl >> 16) & 0x1f) != 4);
|
||||
while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
|
||||
;
|
||||
}
|
||||
|
||||
u32 fuse_read(u32 addr)
|
||||
|
@ -118,24 +176,25 @@ u32 fuse_read(u32 addr)
|
|||
FUSE(FUSE_ADDR) = addr;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
fuse_wait_idle();
|
||||
|
||||
return FUSE(FUSE_RDATA);
|
||||
}
|
||||
|
||||
void fuse_read_array(u32 *words)
|
||||
{
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192;
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
||||
FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM;
|
||||
|
||||
for (u32 i = 0; i < array_size; i++)
|
||||
words[i] = fuse_read(i);
|
||||
}
|
||||
|
||||
static u32 _parity32_even(u32 *words, u32 count)
|
||||
static u32 _parity32_even(const u32 *words, u32 count)
|
||||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
{
|
||||
acc ^= words[i];
|
||||
}
|
||||
|
||||
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
|
||||
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
|
||||
u32 x = hi ^ lo;
|
||||
|
@ -151,26 +210,26 @@ static int _patch_hash_one(u32 *word)
|
|||
u32 bits20_31 = *word & 0xfff00000;
|
||||
u32 parity_bit = _parity32_even(&bits20_31, 1);
|
||||
u32 hash = 0;
|
||||
|
||||
for (u32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (*word & (1 << (20 + i)))
|
||||
{
|
||||
hash ^= hash_vals[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*word ^= 1 << 24;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++)
|
||||
{
|
||||
if (hash_vals[i] == hash)
|
||||
|
@ -179,6 +238,7 @@ static int _patch_hash_one(u32 *word)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -199,9 +259,7 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
for (u32 bitpos = 0; bitpos < 32; bitpos++)
|
||||
{
|
||||
if ((w >> bitpos) & 1)
|
||||
{
|
||||
hash ^= 0x4000 + i * 32 + bitpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,16 +271,14 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
words[0] ^= 0x8000;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
u32 bitcount = hash - 0x4000;
|
||||
if (bitcount < 16 || bitcount >= count * 32)
|
||||
{
|
||||
|
@ -230,14 +286,11 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
for (u32 bitpos = 0; bitpos < 15; bitpos++)
|
||||
{
|
||||
if ((hash >> bitpos) & 1)
|
||||
{
|
||||
num_set++;
|
||||
}
|
||||
}
|
||||
if (num_set != 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
words[0] ^= hash;
|
||||
return 1;
|
||||
}
|
||||
|
@ -250,29 +303,35 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 word0;
|
||||
u32 total_read = 0;
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
if (ipatch_count)
|
||||
{
|
||||
|
@ -285,13 +344,14 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||
ipatch(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
|
@ -303,33 +363,48 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 word0;
|
||||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
bool t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
|
||||
u32 *evp_thunk_tmp = (u32 *)malloc(sizeof(evp_thunk_template));
|
||||
|
||||
memcpy(evp_thunk_tmp, evp_thunk_template, sizeof(evp_thunk_template));
|
||||
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
|
||||
|
||||
if (t210b01)
|
||||
memcpy(&evp_thunk_tmp[15], evp_thunk_func_offsets_t210b01, sizeof(evp_thunk_func_offsets_t210b01));
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
u32 insn_count = word_count - ipatch_count - 1;
|
||||
if (insn_count)
|
||||
|
@ -338,10 +413,10 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
{
|
||||
evp_thunk_dst_addr = (void *)iram_evp_thunks;
|
||||
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
|
||||
evp_thunk_dst_addr += evp_thunk_template_len;
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_tmp, sizeof(evp_thunk_template));
|
||||
evp_thunk_dst_addr += sizeof(evp_thunk_template);
|
||||
evp_thunk_written = 1;
|
||||
*iram_evp_thunks_len = evp_thunk_template_len;
|
||||
*iram_evp_thunks_len = sizeof(evp_thunk_template);
|
||||
|
||||
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
|
||||
}
|
||||
|
@ -351,16 +426,22 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
evp_thunk_dst_addr += thunk_patch_len;
|
||||
*iram_evp_thunks_len += thunk_patch_len;
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
free(evp_thunk_tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -372,7 +453,7 @@ bool fuse_check_patched_rcm()
|
|||
|
||||
// Check if RCM is ipatched.
|
||||
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||
u32 word_addr = 191;
|
||||
u32 word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
|
|
318
bdk/soc/fuse.h
318
bdk/soc/fuse.h
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -22,72 +23,291 @@
|
|||
#include <utils/types.h>
|
||||
|
||||
/*! Fuse registers. */
|
||||
#define FUSE_CTRL 0x0
|
||||
#define FUSE_ADDR 0x4
|
||||
#define FUSE_RDATA 0x8
|
||||
#define FUSE_WDATA 0xC
|
||||
#define FUSE_TIME_RD1 0x10
|
||||
#define FUSE_TIME_RD2 0x14
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
#define FUSE_SKU_INFO 0x110
|
||||
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
||||
#define FUSE_CPU_IDDQ_CALIB 0x118
|
||||
#define FUSE_OPT_FT_REV 0x128
|
||||
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
|
||||
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
|
||||
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
|
||||
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
|
||||
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
|
||||
#define FUSE_SOC_IDDQ_CALIB 0x140
|
||||
#define FUSE_OPT_CP_REV 0x190
|
||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c
|
||||
#define FUSE_PRIVATE_KEY0 0x1A4
|
||||
#define FUSE_PRIVATE_KEY1 0x1A8
|
||||
#define FUSE_PRIVATE_KEY2 0x1AC
|
||||
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||
#define FUSE_PRIVATE_KEY4 0x1B4
|
||||
#define FUSE_RESERVED_SW 0x1C0
|
||||
#define FUSE_USB_CALIB 0x1F0
|
||||
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||
#define FUSE_OPT_FAB_CODE 0x204
|
||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||
#define FUSE_OPT_LOT_CODE_1 0x20C
|
||||
#define FUSE_OPT_WAFER_ID 0x210
|
||||
#define FUSE_OPT_X_COORDINATE 0x214
|
||||
#define FUSE_OPT_Y_COORDINATE 0x218
|
||||
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||
#define FUSE_RESERVED_ODM28 0x240
|
||||
#define FUSE_USB_CALIB_EXT 0x350
|
||||
#define FUSE_CTRL 0x0
|
||||
#define FUSE_ADDR 0x4
|
||||
#define FUSE_RDATA 0x8
|
||||
#define FUSE_WDATA 0xC
|
||||
#define FUSE_TIME_RD1 0x10
|
||||
#define FUSE_TIME_RD2 0x14
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
#define FUSE_PRIV2RESHIFT 0x3C
|
||||
#define FUSE_FUSETIME_RD0 0x40
|
||||
#define FUSE_FUSETIME_RD1 0x44
|
||||
#define FUSE_FUSETIME_RD2 0x48
|
||||
#define FUSE_FUSETIME_RD3 0x4C
|
||||
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
|
||||
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
|
||||
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
|
||||
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
|
||||
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
|
||||
|
||||
/*! Fuse Cached registers */
|
||||
#define FUSE_RESERVED_ODM8_B01 0x98
|
||||
#define FUSE_RESERVED_ODM9_B01 0x9C
|
||||
#define FUSE_RESERVED_ODM10_B01 0xA0
|
||||
#define FUSE_RESERVED_ODM11_B01 0xA4
|
||||
#define FUSE_RESERVED_ODM12_B01 0xA8
|
||||
#define FUSE_RESERVED_ODM13_B01 0xAC
|
||||
#define FUSE_RESERVED_ODM14_B01 0xB0
|
||||
#define FUSE_RESERVED_ODM15_B01 0xB4
|
||||
#define FUSE_RESERVED_ODM16_B01 0xB8
|
||||
#define FUSE_RESERVED_ODM17_B01 0xBC
|
||||
#define FUSE_RESERVED_ODM18_B01 0xC0
|
||||
#define FUSE_RESERVED_ODM19_B01 0xC4
|
||||
#define FUSE_RESERVED_ODM20_B01 0xC8
|
||||
#define FUSE_RESERVED_ODM21_B01 0xCC
|
||||
#define FUSE_KEK00_B01 0xD0
|
||||
#define FUSE_KEK01_B01 0xD4
|
||||
#define FUSE_KEK02_B01 0xD8
|
||||
#define FUSE_KEK03_B01 0xDC
|
||||
#define FUSE_BEK00_B01 0xE0
|
||||
#define FUSE_BEK01_B01 0xE4
|
||||
#define FUSE_BEK02_B01 0xE8
|
||||
#define FUSE_BEK03_B01 0xEC
|
||||
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
|
||||
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
|
||||
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
|
||||
|
||||
#define FUSE_PRODUCTION_MODE 0x100
|
||||
#define FUSE_JTAG_SECUREID_VALID 0x104
|
||||
#define FUSE_ODM_LOCK 0x108
|
||||
#define FUSE_OPT_OPENGL_EN 0x10C
|
||||
#define FUSE_SKU_INFO 0x110
|
||||
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
||||
#define FUSE_CPU_IDDQ_CALIB 0x118
|
||||
|
||||
#define FUSE_RESERVED_ODM22_B01 0x11C
|
||||
#define FUSE_RESERVED_ODM23_B01 0x120
|
||||
#define FUSE_RESERVED_ODM24_B01 0x124
|
||||
|
||||
#define FUSE_OPT_FT_REV 0x128
|
||||
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
|
||||
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
|
||||
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
|
||||
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
|
||||
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
|
||||
#define FUSE_SOC_IDDQ_CALIB 0x140
|
||||
|
||||
#define FUSE_RESERVED_ODM25_B01 0x144
|
||||
|
||||
#define FUSE_FA 0x148
|
||||
#define FUSE_RESERVED_PRODUCTION 0x14C
|
||||
#define FUSE_HDMI_LANE0_CALIB 0x150
|
||||
#define FUSE_HDMI_LANE1_CALIB 0x154
|
||||
#define FUSE_HDMI_LANE2_CALIB 0x158
|
||||
#define FUSE_HDMI_LANE3_CALIB 0x15C
|
||||
#define FUSE_ENCRYPTION_RATE 0x160
|
||||
#define FUSE_PUBLIC_KEY0 0x164
|
||||
#define FUSE_PUBLIC_KEY1 0x168
|
||||
#define FUSE_PUBLIC_KEY2 0x16C
|
||||
#define FUSE_PUBLIC_KEY3 0x170
|
||||
#define FUSE_PUBLIC_KEY4 0x174
|
||||
#define FUSE_PUBLIC_KEY5 0x178
|
||||
#define FUSE_PUBLIC_KEY6 0x17C
|
||||
#define FUSE_PUBLIC_KEY7 0x180
|
||||
#define FUSE_TSENSOR1_CALIB 0x184
|
||||
#define FUSE_TSENSOR2_CALIB 0x188
|
||||
|
||||
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
|
||||
|
||||
#define FUSE_OPT_CP_REV 0x190
|
||||
#define FUSE_OPT_PFG 0x194
|
||||
#define FUSE_TSENSOR0_CALIB 0x198
|
||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
|
||||
#define FUSE_SECURITY_MODE 0x1A0
|
||||
#define FUSE_PRIVATE_KEY0 0x1A4
|
||||
#define FUSE_PRIVATE_KEY1 0x1A8
|
||||
#define FUSE_PRIVATE_KEY2 0x1AC
|
||||
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||
#define FUSE_PRIVATE_KEY4 0x1B4
|
||||
#define FUSE_ARM_JTAG_DIS 0x1B8
|
||||
#define FUSE_BOOT_DEVICE_INFO 0x1BC
|
||||
#define FUSE_RESERVED_SW 0x1C0
|
||||
#define FUSE_OPT_VP9_DISABLE 0x1C4
|
||||
|
||||
#define FUSE_RESERVED_ODM0 0x1C8
|
||||
#define FUSE_RESERVED_ODM1 0x1CC
|
||||
#define FUSE_RESERVED_ODM2 0x1D0
|
||||
#define FUSE_RESERVED_ODM3 0x1D4
|
||||
#define FUSE_RESERVED_ODM4 0x1D8
|
||||
#define FUSE_RESERVED_ODM5 0x1DC
|
||||
#define FUSE_RESERVED_ODM6 0x1E0
|
||||
#define FUSE_RESERVED_ODM7 0x1E4
|
||||
|
||||
#define FUSE_OBS_DIS 0x1E8
|
||||
|
||||
#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
|
||||
|
||||
#define FUSE_USB_CALIB 0x1F0
|
||||
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
|
||||
#define FUSE_PACKAGE_INFO 0x1FC
|
||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||
#define FUSE_OPT_FAB_CODE 0x204
|
||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||
#define FUSE_OPT_LOT_CODE_1 0x20C
|
||||
#define FUSE_OPT_WAFER_ID 0x210
|
||||
#define FUSE_OPT_X_COORDINATE 0x214
|
||||
#define FUSE_OPT_Y_COORDINATE 0x218
|
||||
#define FUSE_OPT_SEC_DEBUG_EN 0x21C
|
||||
#define FUSE_OPT_OPS_RESERVED 0x220
|
||||
#define FUSE_SATA_CALIB 0x224
|
||||
|
||||
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
|
||||
|
||||
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||
#define FUSE_TSENSOR3_CALIB 0x22C
|
||||
#define FUSE_CLOCK_BONDOUT0 0x230
|
||||
#define FUSE_CLOCK_BONDOUT1 0x234
|
||||
|
||||
#define FUSE_RESERVED_ODM26_B01 0x238
|
||||
#define FUSE_RESERVED_ODM27_B01 0x23C
|
||||
#define FUSE_RESERVED_ODM28_B01 0x240
|
||||
|
||||
#define FUSE_OPT_SAMPLE_TYPE 0x244
|
||||
#define FUSE_OPT_SUBREVISION 0x248
|
||||
#define FUSE_OPT_SW_RESERVED_0 0x24C
|
||||
#define FUSE_OPT_SW_RESERVED_1 0x250
|
||||
#define FUSE_TSENSOR4_CALIB 0x254
|
||||
#define FUSE_TSENSOR5_CALIB 0x258
|
||||
#define FUSE_TSENSOR6_CALIB 0x25C
|
||||
#define FUSE_TSENSOR7_CALIB 0x260
|
||||
#define FUSE_OPT_PRIV_SEC_DIS 0x264
|
||||
#define FUSE_PKC_DISABLE 0x268
|
||||
|
||||
#define FUSE_BOOT_SECURITY_INFO_B01 0x268
|
||||
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
|
||||
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
|
||||
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
|
||||
|
||||
#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
|
||||
#define FUSE_TSENSOR_COMMON 0x280
|
||||
#define FUSE_OPT_CP_BIN 0x284
|
||||
#define FUSE_OPT_GPU_DISABLE 0x288
|
||||
#define FUSE_OPT_FT_BIN 0x28C
|
||||
#define FUSE_OPT_DONE_MAP 0x290
|
||||
|
||||
#define FUSE_RESERVED_ODM29_B01 0x294
|
||||
|
||||
#define FUSE_APB2JTAG_DISABLE 0x298
|
||||
#define FUSE_ODM_INFO 0x29C
|
||||
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
|
||||
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
|
||||
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
|
||||
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
|
||||
#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
|
||||
|
||||
#define FUSE_WOA_SKU_FLAG 0x2C0
|
||||
#define FUSE_ECO_RESERVE_1 0x2C4
|
||||
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
|
||||
#define FUSE_PRODUCTION_MONTH 0x2CC
|
||||
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
|
||||
#define FUSE_TSENSOR9_CALIB 0x2D4
|
||||
#define FUSE_VMIN_CALIBRATION 0x2DC
|
||||
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
|
||||
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
|
||||
#define FUSE_SECURE_PROVISION_INDEX 0x2E8
|
||||
#define FUSE_SECURE_PROVISION_INFO 0x2EC
|
||||
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
|
||||
#define FUSE_SPARE_ENDIS 0x2F4
|
||||
#define FUSE_ECO_RESERVE_0 0x2F8
|
||||
#define FUSE_RESERVED_CALIB0 0x304
|
||||
#define FUSE_RESERVED_CALIB1 0x308
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
|
||||
#define FUSE_OPT_CPU_DISABLE 0x314
|
||||
#define FUSE_OPT_CPU_DISABLE_CP1 0x318
|
||||
#define FUSE_TSENSOR10_CALIB 0x31C
|
||||
#define FUSE_TSENSOR10_CALIB_AUX 0x320
|
||||
#define FUSE_OPT_RAM_SVOP_DP 0x324
|
||||
#define FUSE_OPT_RAM_SVOP_PDP 0x328
|
||||
#define FUSE_OPT_RAM_SVOP_REG 0x32C
|
||||
#define FUSE_OPT_RAM_SVOP_SP 0x330
|
||||
#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
|
||||
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
|
||||
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
|
||||
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
|
||||
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
|
||||
#define FUSE_OPT_ROM_SVOP_SP_B01 0x334
|
||||
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
|
||||
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
|
||||
#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
|
||||
#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
|
||||
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
|
||||
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
|
||||
#define FUSE_USB_CALIB_EXT 0x350
|
||||
#define FUSE_RESERVED_FIELD 0x354
|
||||
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
|
||||
#define FUSE_SPARE_BIT_0 0x380
|
||||
//...
|
||||
#define FUSE_SPARE_BIT_31 0x3FC
|
||||
|
||||
/*! Fuse commands. */
|
||||
#define FUSE_READ 0x1
|
||||
#define FUSE_WRITE 0x2
|
||||
#define FUSE_SENSE 0x3
|
||||
#define FUSE_IDLE 0x0
|
||||
#define FUSE_READ 0x1
|
||||
#define FUSE_WRITE 0x2
|
||||
#define FUSE_SENSE 0x3
|
||||
#define FUSE_CMD_MASK 0x3
|
||||
|
||||
/*! Fuse status. */
|
||||
#define FUSE_STATUS_RESET 0
|
||||
#define FUSE_STATUS_POST_RESET 1
|
||||
#define FUSE_STATUS_LOAD_ROW0 2
|
||||
#define FUSE_STATUS_LOAD_ROW1 3
|
||||
#define FUSE_STATUS_IDLE 4
|
||||
#define FUSE_STATUS_READ_SETUP 5
|
||||
#define FUSE_STATUS_READ_STROBE 6
|
||||
#define FUSE_STATUS_SAMPLE_FUSES 7
|
||||
#define FUSE_STATUS_READ_HOLD 8
|
||||
#define FUSE_STATUS_FUSE_SRC_SETUP 9
|
||||
#define FUSE_STATUS_WRITE_SETUP 10
|
||||
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
|
||||
#define FUSE_STATUS_WRITE_PROGRAM 12
|
||||
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
|
||||
#define FUSE_STATUS_FUSE_SRC_HOLD 14
|
||||
#define FUSE_STATUS_LOAD_RIR 15
|
||||
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
|
||||
#define FUSE_STATUS_READ_DEASSERT_PD 17
|
||||
|
||||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
#define FUSE_ARRAY_WORDS_NUM 192
|
||||
#define FUSE_ARRAY_WORDS_NUM_B01 256
|
||||
|
||||
enum
|
||||
{
|
||||
FUSE_NX_HW_TYPE_ICOSA,
|
||||
FUSE_NX_HW_TYPE_IOWA,
|
||||
FUSE_NX_HW_TYPE_HOAG
|
||||
FUSE_NX_HW_TYPE_HOAG,
|
||||
FUSE_NX_HW_TYPE_AULA
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FUSE_NX_HW_STATE_PROD,
|
||||
FUSE_NX_HW_STATE_DEV
|
||||
};
|
||||
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
u32 fuse_read_odm_keygen_rev();
|
||||
u32 fuse_read_dramid(bool raw_id);
|
||||
u32 fuse_read_hw_state();
|
||||
u32 fuse_read_hw_type();
|
||||
u8 fuse_count_burnt(u32 val);
|
||||
int fuse_set_sbk();
|
||||
void fuse_wait_idle();
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,23 +18,27 @@
|
|||
#include <soc/gpio.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||
#define GPIO_PORT_OFFSET(port) ((GPIO_BANK_IDX(port) << 8) + (((port) % 4) << 2))
|
||||
|
||||
#define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_CNF_OFFSET(port) (0x00 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OE_OFFSET(port) (0x10 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OUT_OFFSET(port) (0x20 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_IN_OFFSET(port) (0x30 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_DB_CTRL_OFFSET(port) (0xB0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_DB_CNT_OFFSET(port) (0xF0 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_IRQ_BANK1 32
|
||||
#define GPIO_IRQ_BANK2 33
|
||||
|
@ -52,7 +56,7 @@ static u8 gpio_bank_irq_ids[8] = {
|
|||
|
||||
void gpio_config(u32 port, u32 pins, int mode)
|
||||
{
|
||||
u32 offset = GPIO_CNF_OFFSET(port);
|
||||
const u32 offset = GPIO_CNF_OFFSET(port);
|
||||
|
||||
if (mode)
|
||||
GPIO(offset) |= pins;
|
||||
|
@ -64,7 +68,7 @@ void gpio_config(u32 port, u32 pins, int mode)
|
|||
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_OE_OFFSET(port);
|
||||
const u32 port_offset = GPIO_OE_OFFSET(port);
|
||||
|
||||
if (enable)
|
||||
GPIO(port_offset) |= pins;
|
||||
|
@ -76,7 +80,7 @@ void gpio_output_enable(u32 port, u32 pins, int enable)
|
|||
|
||||
void gpio_write(u32 port, u32 pins, int high)
|
||||
{
|
||||
u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||
const u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||
|
||||
if (high)
|
||||
GPIO(port_offset) |= pins;
|
||||
|
@ -86,16 +90,49 @@ void gpio_write(u32 port, u32 pins, int high)
|
|||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_direction_input(u32 port, u32 pins)
|
||||
{
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
|
||||
}
|
||||
|
||||
void gpio_direction_output(u32 port, u32 pins, int high)
|
||||
{
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
gpio_write(port, pins, high);
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE);
|
||||
}
|
||||
|
||||
int gpio_read(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
const u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
|
||||
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||
}
|
||||
|
||||
void gpio_set_debounce(u32 port, u32 pins, u32 ms)
|
||||
{
|
||||
const u32 db_ctrl_offset = GPIO_DB_CTRL_OFFSET(port);
|
||||
const u32 db_cnt_offset = GPIO_DB_CNT_OFFSET(port);
|
||||
|
||||
if (ms)
|
||||
{
|
||||
if (ms > 255)
|
||||
ms = 255;
|
||||
|
||||
// Debounce time affects all pins of the same port.
|
||||
GPIO(db_cnt_offset) = ms;
|
||||
GPIO(db_ctrl_offset) = (pins << 8) | pins;
|
||||
}
|
||||
else
|
||||
GPIO(db_ctrl_offset) = (pins << 8) | 0;
|
||||
|
||||
(void)GPIO(db_ctrl_offset); // Commit the write.
|
||||
}
|
||||
|
||||
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||
|
||||
GPIO(port_offset) |= pins;
|
||||
|
||||
|
@ -104,10 +141,10 @@ static void _gpio_interrupt_clear(u32 port, u32 pins)
|
|||
|
||||
int gpio_interrupt_status(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||
const u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||
const u32 enabled_mask = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||
|
||||
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
||||
int status = ((GPIO(port_offset) & pins) && enabled_mask) ? 1 : 0;
|
||||
|
||||
// Clear the interrupt status.
|
||||
if (status)
|
||||
|
@ -118,7 +155,7 @@ int gpio_interrupt_status(u32 port, u32 pins)
|
|||
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||
|
||||
// Clear any possible stray interrupt.
|
||||
_gpio_interrupt_clear(port, pins);
|
||||
|
@ -133,7 +170,7 @@ void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
|||
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||
|
||||
u32 val = GPIO(port_offset);
|
||||
|
||||
|
@ -162,7 +199,7 @@ void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
|||
|
||||
u32 gpio_get_bank_irq_id(u32 port)
|
||||
{
|
||||
u32 bank_idx = GPIO_BANK_IDX(port);
|
||||
const u32 bank_idx = GPIO_BANK_IDX(port);
|
||||
|
||||
return gpio_bank_irq_ids[bank_idx];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -85,8 +85,11 @@
|
|||
|
||||
void gpio_config(u32 port, u32 pins, int mode);
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_direction_input(u32 port, u32 pins);
|
||||
void gpio_direction_output(u32 port, u32 pins, int high);
|
||||
void gpio_write(u32 port, u32 pins, int high);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
void gpio_set_debounce(u32 port, u32 pins, u32 ms);
|
||||
int gpio_interrupt_status(u32 port, u32 pins);
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,7 +18,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <soc/hw_init.h>
|
||||
#include <gfx/di.h>
|
||||
#include <display/di.h>
|
||||
#include <display/vic.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <sec/se.h>
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/uart.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
|
@ -39,14 +41,26 @@
|
|||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <thermal/fan.h>
|
||||
#include <thermal/tmp451.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
u32 hw_rst_status;
|
||||
u32 hw_rst_reason;
|
||||
|
||||
u32 hw_get_chip_id()
|
||||
{
|
||||
if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
|
||||
return GP_HIDREV_MAJOR_T210B01;
|
||||
else
|
||||
return GP_HIDREV_MAJOR_T210;
|
||||
}
|
||||
|
||||
/*
|
||||
* CLK_OSC - 38.4 MHz crystal.
|
||||
* CLK_M - 19.2 MHz (osc/2).
|
||||
|
@ -56,37 +70,48 @@ extern volatile nyx_storage_t *nyx_str;
|
|||
* PCLK - 68MHz init (-> 136MHz -> OC/4).
|
||||
*/
|
||||
|
||||
u32 hw_get_chip_id()
|
||||
{
|
||||
if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
|
||||
return GP_HIDREV_MAJOR_T210B01;
|
||||
else
|
||||
return GP_HIDREV_MAJOR_T210;
|
||||
}
|
||||
|
||||
static void _config_oscillators()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | (4 << 23); // LP0 EMC2TMC_CFG_XM2COMP_PU_VREF_SEL_RANGE.
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
}
|
||||
|
||||
void hw_config_arbiter(bool reset)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x0040090;
|
||||
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x12024C2;
|
||||
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x2201209;
|
||||
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320365B;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
|
||||
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
|
||||
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
|
||||
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
|
||||
}
|
||||
}
|
||||
|
||||
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
|
||||
static void _config_gpios(bool nx_hoag)
|
||||
{
|
||||
// Clamp inputs when tristated.
|
||||
|
@ -94,53 +119,39 @@ static void _config_gpios(bool nx_hoag)
|
|||
|
||||
if (!nx_hoag)
|
||||
{
|
||||
// Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
|
||||
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
|
||||
|
||||
// Set pin mode for UARTB/C TX pins.
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
|
||||
// Enable input logic for UARTB/C TX pins.
|
||||
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
|
||||
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
|
||||
}
|
||||
|
||||
// Set Joy-Con IsAttached direction.
|
||||
// Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
|
||||
// Set Joy-Con IsAttached mode.
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
|
||||
// Enable input logic for Joy-Con IsAttached pins.
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
// Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
|
||||
gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
|
||||
gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
|
||||
|
||||
pinmux_config_i2c(I2C_1);
|
||||
pinmux_config_i2c(I2C_5);
|
||||
pinmux_config_uart(UART_A);
|
||||
|
||||
// Configure volume up/down as inputs.
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
|
||||
|
||||
// Configure HOME as inputs.
|
||||
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
// Configure HOME as input. (Shared with UARTB RTS).
|
||||
PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
|
||||
|
||||
// Power button can be configured for hoag here. Only SKU where it's connected.
|
||||
}
|
||||
|
||||
static void _config_pmc_scratch()
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
|
@ -173,8 +184,9 @@ static void _mbist_workaround()
|
|||
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
|
||||
// Set SLCG overrides.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
|
||||
VIC(0x8C) = 0xFFFFFFFF;
|
||||
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||
usleep(2);
|
||||
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
|
@ -241,70 +253,68 @@ static void _mbist_workaround()
|
|||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
static void _config_se_brom()
|
||||
{
|
||||
// Enable fuse clock.
|
||||
// Enable Fuse visibility.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Skip SBK/SSK if sept was run.
|
||||
bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
|
||||
if (!sbk_skip)
|
||||
{
|
||||
// Bootrom part we skipped.
|
||||
u32 sbk[4] = {
|
||||
FUSE(FUSE_PRIVATE_KEY0),
|
||||
FUSE(FUSE_PRIVATE_KEY1),
|
||||
FUSE(FUSE_PRIVATE_KEY2),
|
||||
FUSE(FUSE_PRIVATE_KEY3)
|
||||
};
|
||||
// Set SBK to slot 14.
|
||||
se_aes_key_set(14, sbk, 0x10);
|
||||
// Try to set SBK from fuses. If patched, skip.
|
||||
fuse_set_sbk();
|
||||
|
||||
// Lock SBK from being read.
|
||||
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
}
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||
memset((void *)TZRAM_BASE, 0, 0x10000);
|
||||
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
|
||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
||||
SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;
|
||||
|
||||
// Clear the boot reason to avoid problems later
|
||||
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
||||
PMC(APBDEV_PMC_RST_STATUS) = 0x0;
|
||||
// Clear SE interrupts.
|
||||
SE(SE_INT_STATUS_REG) = SE_INT_OP_DONE | SE_INT_OUT_DONE | SE_INT_OUT_LL_BUF_WR | SE_INT_IN_DONE | SE_INT_IN_LL_BUF_RD;
|
||||
|
||||
// Save reset reason.
|
||||
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
|
||||
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
|
||||
|
||||
// Clear the boot reason to avoid problems later.
|
||||
PMC(APBDEV_PMC_SCRATCH200) = 0;
|
||||
PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
|
||||
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
|
||||
}
|
||||
|
||||
static void _config_regulators(bool tegra_t210)
|
||||
static void _config_regulators(bool tegra_t210, bool nx_hoag)
|
||||
{
|
||||
// Set RTC/AO domain to POR voltage.
|
||||
if (tegra_t210)
|
||||
max77620_regulator_set_voltage(REGULATOR_LDO4, 1000000);
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO4, 1000000);
|
||||
|
||||
// Disable low battery shutdown monitor.
|
||||
max77620_low_battery_monitor_config(false);
|
||||
|
||||
// Disable SDMMC1 IO power.
|
||||
// Power on all relevant rails in case we came out of warmboot. Only keep MEM/MEM_COMP and SDMMC1 states.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_MEM_COMP | PMC_NO_IOPOWER_SDMMC1 | PMC_NO_IOPOWER_MEM;
|
||||
|
||||
// Make sure SDMMC1 IO/Core are powered off.
|
||||
max7762x_regulator_enable(REGULATOR_LDO2, false);
|
||||
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
|
||||
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
|
||||
(void)PMC(APBDEV_PMC_NO_IOPOWER);
|
||||
sd_power_cycle_time_start = get_tmr_ms();
|
||||
|
||||
// Disable backup battery charger.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||
BIT(6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
|
||||
// Set PWR delay for forced shutdown off to 6s.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT));
|
||||
|
||||
if (tegra_t210)
|
||||
{
|
||||
// Configure all Flexible Power Sequencers for MAX77620.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (0 << MAX77620_FPS_EN_SRC_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
max77620_regulator_config_fps(REGULATOR_LDO4);
|
||||
|
@ -313,54 +323,67 @@ static void _config_regulators(bool tegra_t210)
|
|||
max77620_regulator_config_fps(REGULATOR_SD1);
|
||||
max77620_regulator_config_fps(REGULATOR_SD3);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
|
||||
(4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
|
||||
// Set GPIO3 to FPS0 for SYS 3V3 EN. Enabled when FPS0 is enabled.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, (4 << MAX77620_FPS_PU_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT));
|
||||
|
||||
// Set vdd_core voltage to 1.125V.
|
||||
max77620_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
||||
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
||||
|
||||
// Fix CPU/GPU after a L4T warmboot.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
|
||||
// Power down CPU/GPU regulators after L4T warmboot.
|
||||
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
|
||||
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
|
||||
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
|
||||
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
|
||||
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
|
||||
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
|
||||
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
|
||||
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||
// Set POR configuration.
|
||||
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
|
||||
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tegra X1+ set vdd_core voltage to 1.05V.
|
||||
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
|
||||
|
||||
// Power on SD2 regulator for supplying LDO0/1/8.
|
||||
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
||||
|
||||
// Set slew rate and enable SD2 regulator.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) |
|
||||
(MAX77620_POWER_MODE_NORMAL << MAX77620_SD_POWER_MODE_SHIFT) |
|
||||
MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
||||
|
||||
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
|
||||
if (nx_hoag)
|
||||
{
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO8, true);
|
||||
}
|
||||
}
|
||||
else // Tegra X1+ set vdd_core voltage to 1.05V.
|
||||
max77620_regulator_set_voltage(REGULATOR_SD0, 1050000);
|
||||
}
|
||||
|
||||
void hw_init()
|
||||
{
|
||||
// Get Chip ID.
|
||||
// Get Chip ID and SKU.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||
|
||||
// Bootrom stuff we skipped by going through rcm.
|
||||
_config_se_brom();
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
|
||||
|
||||
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
|
||||
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
|
||||
|
||||
// Perform Memory Built-In Self Test WAR if T210.
|
||||
if (tegra_t210)
|
||||
_mbist_workaround();
|
||||
|
||||
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
|
||||
|
||||
// Enable Security Engine clock.
|
||||
clock_enable_se();
|
||||
|
||||
// Enable Fuse clock.
|
||||
// Enable Fuse visibility.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Disable Fuse programming.
|
||||
|
@ -375,13 +398,7 @@ void hw_init()
|
|||
// Initialize pin configuration.
|
||||
_config_gpios(nx_hoag);
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
clock_enable_uart(DEBUG_UART_PORT);
|
||||
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE);
|
||||
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
||||
#endif
|
||||
|
||||
// Enable Dynamic Voltage and Frequency Scaling device clock.
|
||||
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
|
||||
clock_enable_cl_dvfs();
|
||||
|
||||
// Enable clocks to I2C1 and I2CPWR.
|
||||
|
@ -394,86 +411,114 @@ void hw_init()
|
|||
// Initialize I2C5, mandatory for PMIC.
|
||||
i2c_init(I2C_5);
|
||||
|
||||
//! TODO: Why? Device is NFC MCU on Lite.
|
||||
if (nx_hoag)
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO8, 2800000, MAX77620_POWER_MODE_NORMAL);
|
||||
// Initialize various regulators based on Erista/Mariko platform.
|
||||
_config_regulators(tegra_t210, nx_hoag);
|
||||
|
||||
// Initialize I2C1 for various power related devices.
|
||||
i2c_init(I2C_1);
|
||||
|
||||
// Initialize various regulators based on Erista/Mariko platform.
|
||||
_config_regulators(tegra_t210);
|
||||
|
||||
// Enable charger in case it's disabled.
|
||||
bq24193_enable_charger();
|
||||
|
||||
_config_pmc_scratch(); // Missing from 4.x+
|
||||
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||
|
||||
// Disable TZRAM shutdown control and lock the regs.
|
||||
// Power on T210B01 shadow TZRAM and lock the reg.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3;
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
}
|
||||
|
||||
// Set arbiter.
|
||||
hw_config_arbiter(false);
|
||||
|
||||
// Initialize External memory controller and configure DRAM parameters.
|
||||
sdram_init();
|
||||
|
||||
bpmp_mmu_enable();
|
||||
|
||||
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
|
||||
clock_enable_host1x();
|
||||
|
||||
#ifdef DEBUG_UART_PORT
|
||||
// Setup debug uart port.
|
||||
#if (DEBUG_UART_PORT == UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
#elif (DEBUG_UART_PORT == UART_C)
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
#endif
|
||||
pinmux_config_uart(DEBUG_UART_PORT);
|
||||
clock_enable_uart(DEBUG_UART_PORT);
|
||||
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
|
||||
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hw_reinit_workaround(bool extra_reconfig, u32 magic)
|
||||
void hw_deinit(bool coreboot, u32 bl_magic)
|
||||
{
|
||||
// Disable BPMP max clock.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// Scale down BPMP clock.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
#ifdef NYX
|
||||
// Deinit touchscreen, 5V regulators and Joy-Con.
|
||||
#ifdef BDK_HW_EXTRA_DEINIT
|
||||
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
|
||||
vic_end();
|
||||
tmp451_end();
|
||||
fan_set_duty(0);
|
||||
touch_power_off();
|
||||
set_fan_duty(0);
|
||||
jc_deinit();
|
||||
regulator_disable_5v(REGULATOR_5V_ALL);
|
||||
clock_disable_uart(UART_B);
|
||||
clock_disable_uart(UART_C);
|
||||
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||
#endif
|
||||
|
||||
// Flush/disable MMU cache and set DRAM clock to 204MHz.
|
||||
bpmp_mmu_disable();
|
||||
// set DRAM clock to 204MHz.
|
||||
minerva_change_freq(FREQ_204);
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
// Flush/disable MMU cache.
|
||||
bpmp_mmu_disable();
|
||||
|
||||
if (extra_reconfig)
|
||||
// Reset arbiter.
|
||||
hw_config_arbiter(true);
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
}
|
||||
|
||||
// Do coreboot mitigations.
|
||||
if (coreboot)
|
||||
{
|
||||
msleep(10);
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;
|
||||
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
// Disable Joy-con GPIOs.
|
||||
// Disable Joy-con detect in order to restore UART TX.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
|
||||
// Reinstate SD controller power.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
|
||||
}
|
||||
|
||||
// Power off display.
|
||||
display_end();
|
||||
|
||||
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
|
||||
if (magic == 0xBAADF00D)
|
||||
// Seamless display or display power off.
|
||||
switch (bl_magic)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
|
||||
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
msleep(200);
|
||||
case BL_MAGIC_CRBOOT_SLD:;
|
||||
// Set pwm to 0%, switch to gpio mode and restore pwm duty.
|
||||
u32 brightness = display_get_backlight_brightness();
|
||||
display_backlight_brightness(0, 1000);
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
display_backlight_brightness(brightness, 0);
|
||||
break;
|
||||
case BL_MAGIC_L4TLDR_SLD:
|
||||
// Do not disable display or backlight at all.
|
||||
break;
|
||||
default:
|
||||
display_end();
|
||||
clock_disable_host1x();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -20,8 +20,15 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
|
||||
#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1.
|
||||
|
||||
extern u32 hw_rst_status;
|
||||
extern u32 hw_rst_reason;
|
||||
|
||||
void hw_init();
|
||||
void hw_reinit_workaround(bool extra_reconfig, u32 magic);
|
||||
void hw_deinit(bool coreboot, u32 magic);
|
||||
void hw_config_arbiter(bool reset);
|
||||
u32 hw_get_chip_id();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,7 +18,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define I2C_PACKET_PROT_I2C BIT(4)
|
||||
#define I2C_HEADER_CONT_XFER BIT(15)
|
||||
|
@ -81,34 +82,28 @@
|
|||
#define MSTR_CONFIG_LOAD BIT(0)
|
||||
#define TIMEOUT_CONFIG_LOAD BIT(2)
|
||||
|
||||
static const u32 i2c_addrs[] = {
|
||||
0x7000C000, // I2C_1.
|
||||
0x7000C400, // I2C_2.
|
||||
0x7000C500, // I2C_3.
|
||||
0x7000C700, // I2C_4.
|
||||
0x7000D000, // I2C_5.
|
||||
0x7000D100 // I2C_6.
|
||||
};
|
||||
/* I2C_1, 2, 3, 4, 5 and 6. */
|
||||
static const u16 _i2c_base_offsets[6] = { 0x0, 0x400, 0x500, 0x700, 0x1000, 0x1100 };
|
||||
|
||||
static void _i2c_load_cfg_wait(vu32 *base)
|
||||
{
|
||||
base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||
break;
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
|
||||
|
@ -154,7 +149,7 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
|||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
@ -198,15 +193,15 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
|||
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE;
|
||||
|
||||
// Set recv mode.
|
||||
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
|
@ -270,7 +265,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
|||
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
|
@ -352,7 +347,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
|||
|
||||
void i2c_init(u32 i2c_idx)
|
||||
{
|
||||
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
|
||||
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
|
||||
|
@ -362,9 +357,9 @@ void i2c_init(u32 i2c_idx)
|
|||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||
break;
|
||||
usleep(25);
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
|
@ -389,9 +384,9 @@ int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
|||
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
u8 tmp[8];
|
||||
|
||||
if (size > 7)
|
||||
return 0;
|
||||
|
|
|
@ -31,7 +31,7 @@ void i2c_init(u32 i2c_idx);
|
|||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
|
||||
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BPMP-Lite IRQ driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
extern void excp_reset();
|
||||
extern void irq_disable();
|
||||
extern void irq_enable_cpu_irq_exceptions();
|
||||
extern void irq_disable_cpu_irq_exceptions();
|
||||
|
@ -69,29 +71,19 @@ static void _irq_disable_and_ack_all()
|
|||
{
|
||||
u32 enabled_irqs = ICTLR(ctrl_idx, PRI_ICTLR_COP_IER);
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = enabled_irqs;
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs;
|
||||
}
|
||||
}
|
||||
|
||||
static void _irq_ack_source(u32 irq)
|
||||
{
|
||||
u32 ctrl_idx = irq >> 5;
|
||||
u32 bit = irq % 32;
|
||||
|
||||
// Force stop the interrupt as it's serviced here.
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = BIT(bit);
|
||||
}
|
||||
|
||||
void irq_free(u32 irq)
|
||||
{
|
||||
for (u32 idx = 0; idx < IRQ_MAX_HANDLERS; idx++)
|
||||
{
|
||||
if (irqs[idx].irq == irq && irqs[idx].handler)
|
||||
{
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
|
||||
_irq_disable_source(irq);
|
||||
}
|
||||
|
@ -106,10 +98,10 @@ static void _irq_free_all()
|
|||
{
|
||||
_irq_disable_source(irqs[idx].irq);
|
||||
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +111,6 @@ static irq_status_t _irq_handle_source(u32 irq)
|
|||
int status = IRQ_NONE;
|
||||
|
||||
_irq_disable_source(irq);
|
||||
_irq_ack_source(irq);
|
||||
|
||||
u32 idx;
|
||||
for (idx = 0; idx < IRQ_MAX_HANDLERS; idx++)
|
||||
|
@ -133,6 +124,10 @@ static irq_status_t _irq_handle_source(u32 irq)
|
|||
}
|
||||
}
|
||||
|
||||
// Do not re-enable if not handled or error.
|
||||
if (status != IRQ_HANDLED)
|
||||
return status;
|
||||
|
||||
if (irqs[idx].flags & IRQ_FLAG_ONE_OFF)
|
||||
irq_free(irq);
|
||||
else
|
||||
|
@ -148,7 +143,8 @@ void irq_handler()
|
|||
|
||||
if (!irq_init_done)
|
||||
{
|
||||
_irq_ack_source(irq);
|
||||
_irq_disable_source(irq);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -156,9 +152,10 @@ void irq_handler()
|
|||
|
||||
int err = _irq_handle_source(irq);
|
||||
|
||||
//TODO: disable if unhandhled.
|
||||
if (err == IRQ_NONE)
|
||||
gfx_printf("Unhandled IRQ: %d\n", irq);
|
||||
{
|
||||
DPRINTF("Unhandled IRQ got disabled: %d!\n", irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void _irq_init()
|
||||
|
@ -170,6 +167,9 @@ static void _irq_init()
|
|||
|
||||
void irq_end()
|
||||
{
|
||||
if (!irq_init_done)
|
||||
return;
|
||||
|
||||
_irq_free_all();
|
||||
irq_disable_cpu_irq_exceptions();
|
||||
irq_init_done = false;
|
||||
|
@ -182,10 +182,9 @@ void irq_wait_event(u32 irq)
|
|||
_irq_enable_source(irq);
|
||||
|
||||
// Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ.
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ;
|
||||
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
|
||||
|
||||
_irq_disable_source(irq);
|
||||
_irq_ack_source(irq);
|
||||
|
||||
irq_enable_cpu_irq_exceptions();
|
||||
}
|
||||
|
@ -208,10 +207,10 @@ irq_status_t irq_request(u32 irq, irq_handler_t handler, void *data, irq_flags_t
|
|||
DPRINTF("Registered handler, IRQ: %d, Slot: %d\n", irq, idx);
|
||||
DPRINTF("Handler: %08p, Flags: %x\n", (u32)handler, flags);
|
||||
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].handler = handler;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
|
||||
_irq_enable_source(irq);
|
||||
|
||||
|
@ -260,4 +259,14 @@ void __attribute__ ((target("arm"), interrupt ("FIQ"))) fiq_handler()
|
|||
len--;
|
||||
}
|
||||
*/
|
||||
#ifdef BDK_WATCHDOG_FIQ_ENABLE
|
||||
// Set watchdog timeout status and disable WDT and its FIQ signal.
|
||||
watchdog_handle();
|
||||
|
||||
#ifdef BDK_RESTART_BL_ON_WDT
|
||||
// Restart bootloader.
|
||||
excp_reset();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@
|
|||
#define IRQ_EVENT_GPIO_A 162
|
||||
#define IRQ_EVENT_GPIO_B 163
|
||||
#define IRQ_EVENT_GPIO_C 164
|
||||
#define IRQ_EVENT_GPIO_D_T210B01 165
|
||||
#define IRQ_FLOW_RSM_CPU 168
|
||||
#define IRQ_FLOW_RSM_COP 169
|
||||
#define IRQ_TMR_SHARED 170
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue