radeon_legacy_tv.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. #include "drmP.h"
  2. #include "drm_crtc_helper.h"
  3. #include "radeon.h"
  4. /*
  5. * Integrated TV out support based on the GATOS code by
  6. * Federico Ulivi <fulivi@lycos.com>
  7. */
  8. /*
  9. * Limits of h/v positions (hPos & vPos)
  10. */
  11. #define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
  12. #define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
  13. /*
  14. * Unit for hPos (in TV clock periods)
  15. */
  16. #define H_POS_UNIT 10
  17. /*
  18. * Indexes in h. code timing table for horizontal line position adjustment
  19. */
  20. #define H_TABLE_POS1 6
  21. #define H_TABLE_POS2 8
  22. /*
  23. * Limits of hor. size (hSize)
  24. */
  25. #define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
  26. /* tv standard constants */
  27. #define NTSC_TV_CLOCK_T 233
  28. #define NTSC_TV_VFTOTAL 1
  29. #define NTSC_TV_LINES_PER_FRAME 525
  30. #define NTSC_TV_ZERO_H_SIZE 479166
  31. #define NTSC_TV_H_SIZE_UNIT 9478
  32. #define PAL_TV_CLOCK_T 188
  33. #define PAL_TV_VFTOTAL 3
  34. #define PAL_TV_LINES_PER_FRAME 625
  35. #define PAL_TV_ZERO_H_SIZE 473200
  36. #define PAL_TV_H_SIZE_UNIT 9360
  37. /* tv pll setting for 27 mhz ref clk */
  38. #define NTSC_TV_PLL_M_27 22
  39. #define NTSC_TV_PLL_N_27 175
  40. #define NTSC_TV_PLL_P_27 5
  41. #define PAL_TV_PLL_M_27 113
  42. #define PAL_TV_PLL_N_27 668
  43. #define PAL_TV_PLL_P_27 3
  44. /* tv pll setting for 14 mhz ref clk */
  45. #define NTSC_TV_PLL_M_14 33
  46. #define NTSC_TV_PLL_N_14 693
  47. #define NTSC_TV_PLL_P_14 7
  48. #define VERT_LEAD_IN_LINES 2
  49. #define FRAC_BITS 0xe
  50. #define FRAC_MASK 0x3fff
  51. struct radeon_tv_mode_constants {
  52. uint16_t hor_resolution;
  53. uint16_t ver_resolution;
  54. enum radeon_tv_std standard;
  55. uint16_t hor_total;
  56. uint16_t ver_total;
  57. uint16_t hor_start;
  58. uint16_t hor_syncstart;
  59. uint16_t ver_syncstart;
  60. unsigned def_restart;
  61. uint16_t crtcPLL_N;
  62. uint8_t crtcPLL_M;
  63. uint8_t crtcPLL_post_div;
  64. unsigned pix_to_tv;
  65. };
  66. static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = {
  67. 0x0007,
  68. 0x003f,
  69. 0x0263,
  70. 0x0a24,
  71. 0x2a6b,
  72. 0x0a36,
  73. 0x126d, /* H_TABLE_POS1 */
  74. 0x1bfe,
  75. 0x1a8f, /* H_TABLE_POS2 */
  76. 0x1ec7,
  77. 0x3863,
  78. 0x1bfe,
  79. 0x1bfe,
  80. 0x1a2a,
  81. 0x1e95,
  82. 0x0e31,
  83. 0x201b,
  84. 0
  85. };
  86. static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = {
  87. 0x2001,
  88. 0x200d,
  89. 0x1006,
  90. 0x0c06,
  91. 0x1006,
  92. 0x1818,
  93. 0x21e3,
  94. 0x1006,
  95. 0x0c06,
  96. 0x1006,
  97. 0x1817,
  98. 0x21d4,
  99. 0x0002,
  100. 0
  101. };
  102. static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = {
  103. 0x0007,
  104. 0x0058,
  105. 0x027c,
  106. 0x0a31,
  107. 0x2a77,
  108. 0x0a95,
  109. 0x124f, /* H_TABLE_POS1 */
  110. 0x1bfe,
  111. 0x1b22, /* H_TABLE_POS2 */
  112. 0x1ef9,
  113. 0x387c,
  114. 0x1bfe,
  115. 0x1bfe,
  116. 0x1b31,
  117. 0x1eb5,
  118. 0x0e43,
  119. 0x201b,
  120. 0
  121. };
  122. static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = {
  123. 0x2001,
  124. 0x200c,
  125. 0x1005,
  126. 0x0c05,
  127. 0x1005,
  128. 0x1401,
  129. 0x1821,
  130. 0x2240,
  131. 0x1005,
  132. 0x0c05,
  133. 0x1005,
  134. 0x1401,
  135. 0x1822,
  136. 0x2230,
  137. 0x0002,
  138. 0
  139. };
  140. /**********************************************************************
  141. *
  142. * availableModes
  143. *
  144. * Table of all allowed modes for tv output
  145. *
  146. **********************************************************************/
  147. static const struct radeon_tv_mode_constants available_tv_modes[] = {
  148. { /* NTSC timing for 27 Mhz ref clk */
  149. 800, /* horResolution */
  150. 600, /* verResolution */
  151. TV_STD_NTSC, /* standard */
  152. 990, /* horTotal */
  153. 740, /* verTotal */
  154. 813, /* horStart */
  155. 824, /* horSyncStart */
  156. 632, /* verSyncStart */
  157. 625592, /* defRestart */
  158. 592, /* crtcPLL_N */
  159. 91, /* crtcPLL_M */
  160. 4, /* crtcPLL_postDiv */
  161. 1022, /* pixToTV */
  162. },
  163. { /* PAL timing for 27 Mhz ref clk */
  164. 800, /* horResolution */
  165. 600, /* verResolution */
  166. TV_STD_PAL, /* standard */
  167. 1144, /* horTotal */
  168. 706, /* verTotal */
  169. 812, /* horStart */
  170. 824, /* horSyncStart */
  171. 669, /* verSyncStart */
  172. 696700, /* defRestart */
  173. 1382, /* crtcPLL_N */
  174. 231, /* crtcPLL_M */
  175. 4, /* crtcPLL_postDiv */
  176. 759, /* pixToTV */
  177. },
  178. { /* NTSC timing for 14 Mhz ref clk */
  179. 800, /* horResolution */
  180. 600, /* verResolution */
  181. TV_STD_NTSC, /* standard */
  182. 1018, /* horTotal */
  183. 727, /* verTotal */
  184. 813, /* horStart */
  185. 840, /* horSyncStart */
  186. 633, /* verSyncStart */
  187. 630627, /* defRestart */
  188. 347, /* crtcPLL_N */
  189. 14, /* crtcPLL_M */
  190. 8, /* crtcPLL_postDiv */
  191. 1022, /* pixToTV */
  192. },
  193. };
  194. #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
  195. static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder,
  196. uint16_t *pll_ref_freq)
  197. {
  198. struct drm_device *dev = radeon_encoder->base.dev;
  199. struct radeon_device *rdev = dev->dev_private;
  200. struct radeon_crtc *radeon_crtc;
  201. struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
  202. const struct radeon_tv_mode_constants *const_ptr;
  203. struct radeon_pll *pll;
  204. radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
  205. if (radeon_crtc->crtc_id == 1)
  206. pll = &rdev->clock.p2pll;
  207. else
  208. pll = &rdev->clock.p1pll;
  209. if (pll_ref_freq)
  210. *pll_ref_freq = pll->reference_freq;
  211. if (tv_dac->tv_std == TV_STD_NTSC ||
  212. tv_dac->tv_std == TV_STD_NTSC_J ||
  213. tv_dac->tv_std == TV_STD_PAL_M) {
  214. if (pll->reference_freq == 2700)
  215. const_ptr = &available_tv_modes[0];
  216. else
  217. const_ptr = &available_tv_modes[2];
  218. } else {
  219. if (pll->reference_freq == 2700)
  220. const_ptr = &available_tv_modes[1];
  221. else
  222. const_ptr = &available_tv_modes[1]; /* FIX ME */
  223. }
  224. return const_ptr;
  225. }
  226. static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
  227. static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
  228. static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
  229. static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
  230. static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests,
  231. unsigned n_wait_loops, unsigned cnt_threshold)
  232. {
  233. struct drm_device *dev = encoder->dev;
  234. struct radeon_device *rdev = dev->dev_private;
  235. uint32_t save_pll_test;
  236. unsigned int i, j;
  237. WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
  238. save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL);
  239. WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B);
  240. WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
  241. for (i = 0; i < n_tests; i++) {
  242. WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
  243. for (j = 0; j < n_wait_loops; j++)
  244. if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold)
  245. break;
  246. }
  247. WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test);
  248. WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
  249. }
  250. static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder,
  251. uint16_t addr, uint32_t value)
  252. {
  253. struct drm_device *dev = radeon_encoder->base.dev;
  254. struct radeon_device *rdev = dev->dev_private;
  255. uint32_t tmp;
  256. int i = 0;
  257. WREG32(RADEON_TV_HOST_WRITE_DATA, value);
  258. WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
  259. WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
  260. do {
  261. tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
  262. if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
  263. break;
  264. i++;
  265. } while (i < 10000);
  266. WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
  267. }
  268. #if 0 /* included for completeness */
  269. static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr)
  270. {
  271. struct drm_device *dev = radeon_encoder->base.dev;
  272. struct radeon_device *rdev = dev->dev_private;
  273. uint32_t tmp;
  274. int i = 0;
  275. WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
  276. WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
  277. do {
  278. tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
  279. if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
  280. break;
  281. i++;
  282. } while (i < 10000);
  283. WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
  284. return RREG32(RADEON_TV_HOST_READ_DATA);
  285. }
  286. #endif
  287. static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr)
  288. {
  289. uint16_t h_table;
  290. switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
  291. case 0:
  292. h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
  293. break;
  294. case 1:
  295. h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
  296. break;
  297. case 2:
  298. h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
  299. break;
  300. default:
  301. h_table = 0;
  302. break;
  303. }
  304. return h_table;
  305. }
  306. static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr)
  307. {
  308. uint16_t v_table;
  309. switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
  310. case 0:
  311. v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
  312. break;
  313. case 1:
  314. v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
  315. break;
  316. case 2:
  317. v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
  318. break;
  319. default:
  320. v_table = 0;
  321. break;
  322. }
  323. return v_table;
  324. }
  325. static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder)
  326. {
  327. struct drm_device *dev = radeon_encoder->base.dev;
  328. struct radeon_device *rdev = dev->dev_private;
  329. struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
  330. uint16_t h_table, v_table;
  331. uint32_t tmp;
  332. int i;
  333. WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr);
  334. h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr);
  335. v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr);
  336. for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) {
  337. tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]);
  338. radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp);
  339. if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0)
  340. break;
  341. }
  342. for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) {
  343. tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]);
  344. radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp);
  345. if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0)
  346. break;
  347. }
  348. }
  349. static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder)
  350. {
  351. struct drm_device *dev = radeon_encoder->base.dev;
  352. struct radeon_device *rdev = dev->dev_private;
  353. struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
  354. WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart);
  355. WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart);
  356. WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart);
  357. }
  358. static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
  359. {
  360. struct drm_device *dev = encoder->dev;
  361. struct radeon_device *rdev = dev->dev_private;
  362. struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  363. struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
  364. struct radeon_crtc *radeon_crtc;
  365. int restart;
  366. unsigned int h_total, v_total, f_total;
  367. int v_offset, h_offset;
  368. u16 p1, p2, h_inc;
  369. bool h_changed;
  370. const struct radeon_tv_mode_constants *const_ptr;
  371. struct radeon_pll *pll;
  372. radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
  373. if (radeon_crtc->crtc_id == 1)
  374. pll = &rdev->clock.p2pll;
  375. else
  376. pll = &rdev->clock.p1pll;
  377. const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
  378. if (!const_ptr)
  379. return false;
  380. h_total = const_ptr->hor_total;
  381. v_total = const_ptr->ver_total;
  382. if (tv_dac->tv_std == TV_STD_NTSC ||
  383. tv_dac->tv_std == TV_STD_NTSC_J ||
  384. tv_dac->tv_std == TV_STD_PAL_M ||
  385. tv_dac->tv_std == TV_STD_PAL_60)
  386. f_total = NTSC_TV_VFTOTAL + 1;
  387. else
  388. f_total = PAL_TV_VFTOTAL + 1;
  389. /* adjust positions 1&2 in hor. cod timing table */
  390. h_offset = tv_dac->h_pos * H_POS_UNIT;
  391. if (tv_dac->tv_std == TV_STD_NTSC ||
  392. tv_dac->tv_std == TV_STD_NTSC_J ||
  393. tv_dac->tv_std == TV_STD_PAL_M) {
  394. h_offset -= 50;
  395. p1 = hor_timing_NTSC[H_TABLE_POS1];
  396. p2 = hor_timing_NTSC[H_TABLE_POS2];
  397. } else {
  398. p1 = hor_timing_PAL[H_TABLE_POS1];
  399. p2 = hor_timing_PAL[H_TABLE_POS2];
  400. }
  401. p1 = (u16)((int)p1 + h_offset);
  402. p2 = (u16)((int)p2 - h_offset);
  403. h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] ||
  404. p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]);
  405. tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1;
  406. tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2;
  407. /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
  408. h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000;
  409. /* adjust restart */
  410. restart = const_ptr->def_restart;
  411. /*
  412. * convert v_pos TV lines to n. of CRTC pixels
  413. */
  414. if (tv_dac->tv_std == TV_STD_NTSC ||
  415. tv_dac->tv_std == TV_STD_NTSC_J ||
  416. tv_dac->tv_std == TV_STD_PAL_M ||
  417. tv_dac->tv_std == TV_STD_PAL_60)
  418. v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME);
  419. else
  420. v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME);
  421. restart -= v_offset + h_offset;
  422. DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
  423. const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);
  424. tv_dac->tv.hrestart = restart % h_total;
  425. restart /= h_total;
  426. tv_dac->tv.vrestart = restart % v_total;
  427. restart /= v_total;
  428. tv_dac->tv.frestart = restart % f_total;
  429. DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n",
  430. (unsigned)tv_dac->tv.frestart,
  431. (unsigned)tv_dac->tv.vrestart,
  432. (unsigned)tv_dac->tv.hrestart);
  433. /* compute h_inc from hsize */
  434. if (tv_dac->tv_std == TV_STD_NTSC ||
  435. tv_dac->tv_std == TV_STD_NTSC_J ||
  436. tv_dac->tv_std == TV_STD_PAL_M)
  437. h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) /
  438. (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
  439. else
  440. h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) /
  441. (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
  442. tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |
  443. ((u32)h_inc << RADEON_H_INC_SHIFT);
  444. DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
  445. return h_changed;
  446. }
  447. void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
  448. struct drm_display_mode *mode,
  449. struct drm_display_mode *adjusted_mode)
  450. {
  451. struct drm_device *dev = encoder->dev;
  452. struct radeon_device *rdev = dev->dev_private;
  453. struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  454. struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
  455. const struct radeon_tv_mode_constants *const_ptr;
  456. struct radeon_crtc *radeon_crtc;
  457. int i;
  458. uint16_t pll_ref_freq;
  459. uint32_t vert_space, flicker_removal, tmp;
  460. uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl;
  461. uint32_t tv_modulator_cntl1, tv_modulator_cntl2;
  462. uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2;
  463. uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal;
  464. uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl;
  465. uint32_t m, n, p;
  466. const uint16_t *hor_timing;
  467. const uint16_t *vert_timing;
  468. const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq);
  469. if (!const_ptr)
  470. return;
  471. radeon_crtc = to_radeon_crtc(encoder->crtc);
  472. tv_master_cntl = (RADEON_VIN_ASYNC_RST |
  473. RADEON_CRT_FIFO_CE_EN |
  474. RADEON_TV_FIFO_CE_EN |
  475. RADEON_TV_ON);
  476. if (!ASIC_IS_R300(rdev))
  477. tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
  478. if (tv_dac->tv_std == TV_STD_NTSC ||
  479. tv_dac->tv_std == TV_STD_NTSC_J)
  480. tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
  481. tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT |
  482. RADEON_SYNC_TIP_LEVEL |
  483. RADEON_YFLT_EN |
  484. RADEON_UVFLT_EN |
  485. (6 << RADEON_CY_FILT_BLEND_SHIFT));
  486. if (tv_dac->tv_std == TV_STD_NTSC ||
  487. tv_dac->tv_std == TV_STD_NTSC_J) {
  488. tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) |
  489. (0x3b << RADEON_BLANK_LEVEL_SHIFT);
  490. tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
  491. ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
  492. } else if (tv_dac->tv_std == TV_STD_SCART_PAL) {
  493. tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
  494. tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
  495. ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
  496. } else {
  497. tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN |
  498. (0x3b << RADEON_SET_UP_LEVEL_SHIFT) |
  499. (0x3b << RADEON_BLANK_LEVEL_SHIFT);
  500. tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
  501. ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
  502. }
  503. tv_rgb_cntl = (RADEON_RGB_DITHER_EN
  504. | RADEON_TVOUT_SCALE_EN
  505. | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
  506. | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT)
  507. | RADEON_RGB_ATTEN_SEL(0x3)
  508. | RADEON_RGB_ATTEN_VAL(0xc));
  509. if (radeon_crtc->crtc_id == 1)
  510. tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
  511. else {
  512. if (radeon_crtc->rmx_type != RMX_OFF)
  513. tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
  514. else
  515. tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
  516. }
  517. if (tv_dac->tv_std == TV_STD_NTSC ||
  518. tv_dac->tv_std == TV_STD_NTSC_J ||
  519. tv_dac->tv_std == TV_STD_PAL_M ||
  520. tv_dac->tv_std == TV_STD_PAL_60)
  521. vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
  522. else
  523. vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
  524. tmp = RREG32(RADEON_TV_VSCALER_CNTL1);
  525. tmp &= 0xe3ff0000;
  526. tmp |= (vert_space * (1 << FRAC_BITS) / 10000);
  527. tv_vscaler_cntl1 = tmp;
  528. if (pll_ref_freq == 2700)
  529. tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
  530. if (const_ptr->hor_resolution == 1024)
  531. tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
  532. else
  533. tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
  534. /* scale up for int divide */
  535. tmp = const_ptr->ver_total * 2 * 1000;
  536. if (tv_dac->tv_std == TV_STD_NTSC ||
  537. tv_dac->tv_std == TV_STD_NTSC_J ||
  538. tv_dac->tv_std == TV_STD_PAL_M ||
  539. tv_dac->tv_std == TV_STD_PAL_60) {
  540. tmp /= NTSC_TV_LINES_PER_FRAME;
  541. } else {
  542. tmp /= PAL_TV_LINES_PER_FRAME;
  543. }
  544. flicker_removal = (tmp + 500) / 1000;
  545. if (flicker_removal < 2)
  546. flicker_removal = 2;
  547. for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) {
  548. if (flicker_removal == SLOPE_limit[i])
  549. break;
  550. }
  551. tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +
  552. 5001) / 10000 / 8 | ((SLOPE_value[i] *
  553. (1 << (FRAC_BITS - 1)) / 8) << 16);
  554. tv_y_fall_cntl =
  555. (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
  556. RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
  557. 1024;
  558. tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG|
  559. (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
  560. tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0;
  561. tv_vscaler_cntl2 |= (0x10 << 24) |
  562. RADEON_DITHER_MODE |
  563. RADEON_Y_OUTPUT_DITHER_EN |
  564. RADEON_UV_OUTPUT_DITHER_EN |
  565. RADEON_UV_TO_BUF_DITHER_EN;
  566. tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
  567. tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
  568. tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
  569. tv_dac->tv.timing_cntl = tmp;
  570. if (tv_dac->tv_std == TV_STD_NTSC ||
  571. tv_dac->tv_std == TV_STD_NTSC_J ||
  572. tv_dac->tv_std == TV_STD_PAL_M ||
  573. tv_dac->tv_std == TV_STD_PAL_60)
  574. tv_dac_cntl = tv_dac->ntsc_tvdac_adj;
  575. else
  576. tv_dac_cntl = tv_dac->pal_tvdac_adj;
  577. tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
  578. if (tv_dac->tv_std == TV_STD_NTSC ||
  579. tv_dac->tv_std == TV_STD_NTSC_J)
  580. tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
  581. else
  582. tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
  583. if (tv_dac->tv_std == TV_STD_NTSC ||
  584. tv_dac->tv_std == TV_STD_NTSC_J) {
  585. if (pll_ref_freq == 2700) {
  586. m = NTSC_TV_PLL_M_27;
  587. n = NTSC_TV_PLL_N_27;
  588. p = NTSC_TV_PLL_P_27;
  589. } else {
  590. m = NTSC_TV_PLL_M_14;
  591. n = NTSC_TV_PLL_N_14;
  592. p = NTSC_TV_PLL_P_14;
  593. }
  594. } else {
  595. if (pll_ref_freq == 2700) {
  596. m = PAL_TV_PLL_M_27;
  597. n = PAL_TV_PLL_N_27;
  598. p = PAL_TV_PLL_P_27;
  599. } else {
  600. m = PAL_TV_PLL_M_27;
  601. n = PAL_TV_PLL_N_27;
  602. p = PAL_TV_PLL_P_27;
  603. }
  604. }
  605. tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) |
  606. (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
  607. ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
  608. (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
  609. ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
  610. tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) |
  611. ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
  612. ((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) |
  613. RADEON_TVCLK_SRC_SEL_TVPLL |
  614. RADEON_TVPLL_TEST_DIS);
  615. tv_dac->tv.tv_uv_adr = 0xc8;
  616. if (tv_dac->tv_std == TV_STD_NTSC ||
  617. tv_dac->tv_std == TV_STD_NTSC_J ||
  618. tv_dac->tv_std == TV_STD_PAL_M ||
  619. tv_dac->tv_std == TV_STD_PAL_60) {
  620. tv_ftotal = NTSC_TV_VFTOTAL;
  621. hor_timing = hor_timing_NTSC;
  622. vert_timing = vert_timing_NTSC;
  623. } else {
  624. hor_timing = hor_timing_PAL;
  625. vert_timing = vert_timing_PAL;
  626. tv_ftotal = PAL_TV_VFTOTAL;
  627. }
  628. for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
  629. if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0)
  630. break;
  631. }
  632. for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
  633. if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0)
  634. break;
  635. }
  636. radeon_legacy_tv_init_restarts(encoder);
  637. /* play with DAC_CNTL */
  638. /* play with GPIOPAD_A */
  639. /* DISP_OUTPUT_CNTL */
  640. /* use reference freq */
  641. /* program the TV registers */
  642. WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
  643. RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST));
  644. tmp = RREG32(RADEON_TV_DAC_CNTL);
  645. tmp &= ~RADEON_TV_DAC_NBLANK;
  646. tmp |= RADEON_TV_DAC_BGSLEEP |
  647. RADEON_TV_DAC_RDACPD |
  648. RADEON_TV_DAC_GDACPD |
  649. RADEON_TV_DAC_BDACPD;
  650. WREG32(RADEON_TV_DAC_CNTL, tmp);
  651. /* TV PLL */
  652. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
  653. WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl);
  654. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
  655. radeon_wait_pll_lock(encoder, 200, 800, 135);
  656. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
  657. radeon_wait_pll_lock(encoder, 300, 160, 27);
  658. radeon_wait_pll_lock(encoder, 200, 800, 135);
  659. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf);
  660. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
  661. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
  662. WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
  663. /* TV HV */
  664. WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl);
  665. WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1);
  666. WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1);
  667. WREG32(RADEON_TV_HSTART, const_ptr->hor_start);
  668. WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1);
  669. WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1);
  670. WREG32(RADEON_TV_FTOTAL, tv_ftotal);
  671. WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1);
  672. WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2);
  673. WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl);
  674. WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl);
  675. WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl);
  676. WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
  677. RADEON_CRT_ASYNC_RST));
  678. /* TV restarts */
  679. radeon_legacy_write_tv_restarts(radeon_encoder);
  680. /* tv timings */
  681. radeon_restore_tv_timing_tables(radeon_encoder);
  682. WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST));
  683. /* tv std */
  684. WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE));
  685. WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl);
  686. WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1);
  687. WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2);
  688. WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN |
  689. RADEON_C_GRN_EN |
  690. RADEON_CMP_BLU_EN |
  691. RADEON_DAC_DITHER_EN));
  692. WREG32(RADEON_TV_CRC_CNTL, 0);
  693. WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
  694. WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
  695. (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT)));
  696. WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) |
  697. (0x100 << RADEON_Y_GAIN_SHIFT)));
  698. WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
  699. }
  700. void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
  701. uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
  702. uint32_t *v_total_disp, uint32_t *v_sync_strt_wid)
  703. {
  704. struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  705. const struct radeon_tv_mode_constants *const_ptr;
  706. uint32_t tmp;
  707. const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
  708. if (!const_ptr)
  709. return;
  710. *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
  711. (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
  712. tmp = *h_sync_strt_wid;
  713. tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR);
  714. tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
  715. (const_ptr->hor_syncstart & 7);
  716. *h_sync_strt_wid = tmp;
  717. *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
  718. ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
  719. tmp = *v_sync_strt_wid;
  720. tmp &= ~RADEON_CRTC_V_SYNC_STRT;
  721. tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
  722. *v_sync_strt_wid = tmp;
  723. }
  724. static inline int get_post_div(int value)
  725. {
  726. int post_div;
  727. switch (value) {
  728. case 1: post_div = 0; break;
  729. case 2: post_div = 1; break;
  730. case 3: post_div = 4; break;
  731. case 4: post_div = 2; break;
  732. case 6: post_div = 6; break;
  733. case 8: post_div = 3; break;
  734. case 12: post_div = 7; break;
  735. case 16:
  736. default: post_div = 5; break;
  737. }
  738. return post_div;
  739. }
  740. void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
  741. uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
  742. uint32_t *ppll_div_3, uint32_t *pixclks_cntl)
  743. {
  744. struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  745. const struct radeon_tv_mode_constants *const_ptr;
  746. const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
  747. if (!const_ptr)
  748. return;
  749. *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN;
  750. *ppll_ref_div = const_ptr->crtcPLL_M;
  751. *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
  752. *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
  753. *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
  754. }
  755. void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
  756. uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
  757. uint32_t *p2pll_div_0, uint32_t *pixclks_cntl)
  758. {
  759. struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  760. const struct radeon_tv_mode_constants *const_ptr;
  761. const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
  762. if (!const_ptr)
  763. return;
  764. *htotal2_cntl = (const_ptr->hor_total & 0x7);
  765. *p2pll_ref_div = const_ptr->crtcPLL_M;
  766. *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
  767. *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
  768. *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL;
  769. }