atombios_crtc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * Copyright 2007-8 Advanced Micro Devices, Inc.
  3. * Copyright 2008 Red Hat Inc.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. * OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. * Authors: Dave Airlie
  24. * Alex Deucher
  25. */
  26. #include <drm/drmP.h>
  27. #include <drm/drm_crtc_helper.h>
  28. #include <drm/radeon_drm.h>
  29. #include "radeon_fixed.h"
  30. #include "radeon.h"
  31. #include "atom.h"
  32. #include "atom-bits.h"
  33. static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
  34. {
  35. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  36. struct drm_device *dev = crtc->dev;
  37. struct radeon_device *rdev = dev->dev_private;
  38. int index =
  39. GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
  40. ENABLE_CRTC_PS_ALLOCATION args;
  41. memset(&args, 0, sizeof(args));
  42. args.ucCRTC = radeon_crtc->crtc_id;
  43. args.ucEnable = lock;
  44. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  45. }
  46. static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
  47. {
  48. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  49. struct drm_device *dev = crtc->dev;
  50. struct radeon_device *rdev = dev->dev_private;
  51. int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
  52. ENABLE_CRTC_PS_ALLOCATION args;
  53. memset(&args, 0, sizeof(args));
  54. args.ucCRTC = radeon_crtc->crtc_id;
  55. args.ucEnable = state;
  56. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  57. }
  58. static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
  59. {
  60. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  61. struct drm_device *dev = crtc->dev;
  62. struct radeon_device *rdev = dev->dev_private;
  63. int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
  64. ENABLE_CRTC_PS_ALLOCATION args;
  65. memset(&args, 0, sizeof(args));
  66. args.ucCRTC = radeon_crtc->crtc_id;
  67. args.ucEnable = state;
  68. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  69. }
  70. static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
  71. {
  72. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  73. struct drm_device *dev = crtc->dev;
  74. struct radeon_device *rdev = dev->dev_private;
  75. int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
  76. BLANK_CRTC_PS_ALLOCATION args;
  77. memset(&args, 0, sizeof(args));
  78. args.ucCRTC = radeon_crtc->crtc_id;
  79. args.ucBlanking = state;
  80. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  81. }
  82. void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
  83. {
  84. struct drm_device *dev = crtc->dev;
  85. struct radeon_device *rdev = dev->dev_private;
  86. switch (mode) {
  87. case DRM_MODE_DPMS_ON:
  88. if (ASIC_IS_DCE3(rdev))
  89. atombios_enable_crtc_memreq(crtc, 1);
  90. atombios_enable_crtc(crtc, 1);
  91. atombios_blank_crtc(crtc, 0);
  92. break;
  93. case DRM_MODE_DPMS_STANDBY:
  94. case DRM_MODE_DPMS_SUSPEND:
  95. case DRM_MODE_DPMS_OFF:
  96. atombios_blank_crtc(crtc, 1);
  97. atombios_enable_crtc(crtc, 0);
  98. if (ASIC_IS_DCE3(rdev))
  99. atombios_enable_crtc_memreq(crtc, 0);
  100. break;
  101. }
  102. if (mode != DRM_MODE_DPMS_OFF) {
  103. radeon_crtc_load_lut(crtc);
  104. }
  105. }
  106. static void
  107. atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
  108. SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param)
  109. {
  110. struct drm_device *dev = crtc->dev;
  111. struct radeon_device *rdev = dev->dev_private;
  112. SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
  113. int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
  114. conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size);
  115. conv_param.usH_Blanking_Time =
  116. cpu_to_le16(crtc_param->usH_Blanking_Time);
  117. conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size);
  118. conv_param.usV_Blanking_Time =
  119. cpu_to_le16(crtc_param->usV_Blanking_Time);
  120. conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset);
  121. conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
  122. conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset);
  123. conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
  124. conv_param.susModeMiscInfo.usAccess =
  125. cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
  126. conv_param.ucCRTC = crtc_param->ucCRTC;
  127. printk("executing set crtc dtd timing\n");
  128. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
  129. }
  130. void atombios_crtc_set_timing(struct drm_crtc *crtc,
  131. SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *
  132. crtc_param)
  133. {
  134. struct drm_device *dev = crtc->dev;
  135. struct radeon_device *rdev = dev->dev_private;
  136. SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
  137. int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
  138. conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total);
  139. conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp);
  140. conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart);
  141. conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
  142. conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total);
  143. conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp);
  144. conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart);
  145. conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
  146. conv_param.susModeMiscInfo.usAccess =
  147. cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
  148. conv_param.ucCRTC = crtc_param->ucCRTC;
  149. conv_param.ucOverscanRight = crtc_param->ucOverscanRight;
  150. conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft;
  151. conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom;
  152. conv_param.ucOverscanTop = crtc_param->ucOverscanTop;
  153. conv_param.ucReserved = crtc_param->ucReserved;
  154. printk("executing set crtc timing\n");
  155. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param);
  156. }
  157. void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
  158. {
  159. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  160. struct drm_device *dev = crtc->dev;
  161. struct radeon_device *rdev = dev->dev_private;
  162. struct drm_encoder *encoder = NULL;
  163. struct radeon_encoder *radeon_encoder = NULL;
  164. uint8_t frev, crev;
  165. int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
  166. SET_PIXEL_CLOCK_PS_ALLOCATION args;
  167. PIXEL_CLOCK_PARAMETERS *spc1_ptr;
  168. PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
  169. PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
  170. uint32_t sclock = mode->clock;
  171. uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
  172. struct radeon_pll *pll;
  173. int pll_flags = 0;
  174. memset(&args, 0, sizeof(args));
  175. if (ASIC_IS_AVIVO(rdev)) {
  176. uint32_t ss_cntl;
  177. if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
  178. pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
  179. else
  180. pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
  181. /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
  182. if (radeon_crtc->crtc_id == 0) {
  183. ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
  184. WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1);
  185. } else {
  186. ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
  187. WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1);
  188. }
  189. } else {
  190. pll_flags |= RADEON_PLL_LEGACY;
  191. if (mode->clock > 200000) /* range limits??? */
  192. pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
  193. else
  194. pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
  195. }
  196. list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  197. if (encoder->crtc == crtc) {
  198. if (!ASIC_IS_AVIVO(rdev)) {
  199. if (encoder->encoder_type !=
  200. DRM_MODE_ENCODER_DAC)
  201. pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
  202. if (!ASIC_IS_AVIVO(rdev)
  203. && (encoder->encoder_type ==
  204. DRM_MODE_ENCODER_LVDS))
  205. pll_flags |= RADEON_PLL_USE_REF_DIV;
  206. }
  207. radeon_encoder = to_radeon_encoder(encoder);
  208. }
  209. }
  210. if (radeon_crtc->crtc_id == 0)
  211. pll = &rdev->clock.p1pll;
  212. else
  213. pll = &rdev->clock.p2pll;
  214. radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div,
  215. &ref_div, &post_div, pll_flags);
  216. atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
  217. &crev);
  218. switch (frev) {
  219. case 1:
  220. switch (crev) {
  221. case 1:
  222. spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
  223. spc1_ptr->usPixelClock = cpu_to_le16(sclock);
  224. spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
  225. spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
  226. spc1_ptr->ucFracFbDiv = frac_fb_div;
  227. spc1_ptr->ucPostDiv = post_div;
  228. spc1_ptr->ucPpll =
  229. radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
  230. spc1_ptr->ucCRTC = radeon_crtc->crtc_id;
  231. spc1_ptr->ucRefDivSrc = 1;
  232. break;
  233. case 2:
  234. spc2_ptr =
  235. (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
  236. spc2_ptr->usPixelClock = cpu_to_le16(sclock);
  237. spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
  238. spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
  239. spc2_ptr->ucFracFbDiv = frac_fb_div;
  240. spc2_ptr->ucPostDiv = post_div;
  241. spc2_ptr->ucPpll =
  242. radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
  243. spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
  244. spc2_ptr->ucRefDivSrc = 1;
  245. break;
  246. case 3:
  247. if (!encoder)
  248. return;
  249. spc3_ptr =
  250. (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
  251. spc3_ptr->usPixelClock = cpu_to_le16(sclock);
  252. spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
  253. spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
  254. spc3_ptr->ucFracFbDiv = frac_fb_div;
  255. spc3_ptr->ucPostDiv = post_div;
  256. spc3_ptr->ucPpll =
  257. radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
  258. spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
  259. spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id;
  260. spc3_ptr->ucEncoderMode =
  261. atombios_get_encoder_mode(encoder);
  262. break;
  263. default:
  264. DRM_ERROR("Unknown table version %d %d\n", frev, crev);
  265. return;
  266. }
  267. break;
  268. default:
  269. DRM_ERROR("Unknown table version %d %d\n", frev, crev);
  270. return;
  271. }
  272. printk("executing set pll\n");
  273. atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  274. }
  275. int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
  276. struct drm_framebuffer *old_fb)
  277. {
  278. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  279. struct drm_device *dev = crtc->dev;
  280. struct radeon_device *rdev = dev->dev_private;
  281. struct radeon_framebuffer *radeon_fb;
  282. struct drm_gem_object *obj;
  283. struct drm_radeon_gem_object *obj_priv;
  284. uint64_t fb_location;
  285. uint32_t fb_format, fb_pitch_pixels;
  286. if (!crtc->fb)
  287. return -EINVAL;
  288. radeon_fb = to_radeon_framebuffer(crtc->fb);
  289. obj = radeon_fb->obj;
  290. obj_priv = obj->driver_private;
  291. if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
  292. return -EINVAL;
  293. }
  294. switch (crtc->fb->bits_per_pixel) {
  295. case 15:
  296. fb_format =
  297. AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
  298. AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
  299. break;
  300. case 16:
  301. fb_format =
  302. AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
  303. AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
  304. break;
  305. case 24:
  306. case 32:
  307. fb_format =
  308. AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
  309. AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
  310. break;
  311. default:
  312. DRM_ERROR("Unsupported screen depth %d\n",
  313. crtc->fb->bits_per_pixel);
  314. return -EINVAL;
  315. }
  316. /* TODO tiling */
  317. if (radeon_crtc->crtc_id == 0)
  318. WREG32(AVIVO_D1VGA_CONTROL, 0);
  319. else
  320. WREG32(AVIVO_D2VGA_CONTROL, 0);
  321. WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
  322. (u32) fb_location);
  323. WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
  324. radeon_crtc->crtc_offset, (u32) fb_location);
  325. WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
  326. WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
  327. WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
  328. WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
  329. WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
  330. WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
  331. WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
  332. fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
  333. WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
  334. WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
  335. WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
  336. crtc->mode.vdisplay);
  337. x &= ~3;
  338. y &= ~1;
  339. WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
  340. (x << 16) | y);
  341. WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
  342. (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
  343. if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
  344. WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
  345. AVIVO_D1MODE_INTERLEAVE_EN);
  346. else
  347. WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
  348. if (old_fb && old_fb != crtc->fb) {
  349. radeon_fb = to_radeon_framebuffer(old_fb);
  350. radeon_gem_object_unpin(radeon_fb->obj);
  351. }
  352. return 0;
  353. }
  354. int atombios_crtc_mode_set(struct drm_crtc *crtc,
  355. struct drm_display_mode *mode,
  356. struct drm_display_mode *adjusted_mode,
  357. int x, int y, struct drm_framebuffer *old_fb)
  358. {
  359. struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  360. struct drm_device *dev = crtc->dev;
  361. struct radeon_device *rdev = dev->dev_private;
  362. struct drm_encoder *encoder;
  363. SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
  364. /* TODO color tiling */
  365. memset(&crtc_timing, 0, sizeof(crtc_timing));
  366. /* TODO tv */
  367. list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  368. }
  369. crtc_timing.ucCRTC = radeon_crtc->crtc_id;
  370. crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
  371. crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
  372. crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
  373. crtc_timing.usH_SyncWidth =
  374. adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
  375. crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
  376. crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
  377. crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
  378. crtc_timing.usV_SyncWidth =
  379. adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
  380. if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
  381. crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
  382. if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
  383. crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
  384. if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
  385. crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
  386. if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
  387. crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
  388. if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
  389. crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
  390. atombios_crtc_set_pll(crtc, adjusted_mode);
  391. atombios_crtc_set_timing(crtc, &crtc_timing);
  392. if (ASIC_IS_AVIVO(rdev))
  393. atombios_crtc_set_base(crtc, x, y, old_fb);
  394. else {
  395. if (radeon_crtc->crtc_id == 0) {
  396. SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
  397. memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
  398. /* setup FP shadow regs on R4xx */
  399. crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
  400. crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay;
  401. crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay;
  402. crtc_dtd_timing.usH_Blanking_Time =
  403. adjusted_mode->crtc_hblank_end -
  404. adjusted_mode->crtc_hdisplay;
  405. crtc_dtd_timing.usV_Blanking_Time =
  406. adjusted_mode->crtc_vblank_end -
  407. adjusted_mode->crtc_vdisplay;
  408. crtc_dtd_timing.usH_SyncOffset =
  409. adjusted_mode->crtc_hsync_start -
  410. adjusted_mode->crtc_hdisplay;
  411. crtc_dtd_timing.usV_SyncOffset =
  412. adjusted_mode->crtc_vsync_start -
  413. adjusted_mode->crtc_vdisplay;
  414. crtc_dtd_timing.usH_SyncWidth =
  415. adjusted_mode->crtc_hsync_end -
  416. adjusted_mode->crtc_hsync_start;
  417. crtc_dtd_timing.usV_SyncWidth =
  418. adjusted_mode->crtc_vsync_end -
  419. adjusted_mode->crtc_vsync_start;
  420. /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */
  421. /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */
  422. if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
  423. crtc_dtd_timing.susModeMiscInfo.usAccess |=
  424. ATOM_VSYNC_POLARITY;
  425. if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
  426. crtc_dtd_timing.susModeMiscInfo.usAccess |=
  427. ATOM_HSYNC_POLARITY;
  428. if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
  429. crtc_dtd_timing.susModeMiscInfo.usAccess |=
  430. ATOM_COMPOSITESYNC;
  431. if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
  432. crtc_dtd_timing.susModeMiscInfo.usAccess |=
  433. ATOM_INTERLACE;
  434. if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
  435. crtc_dtd_timing.susModeMiscInfo.usAccess |=
  436. ATOM_DOUBLE_CLOCK_MODE;
  437. atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing);
  438. }
  439. radeon_crtc_set_base(crtc, x, y, old_fb);
  440. radeon_legacy_atom_set_surface(crtc);
  441. }
  442. return 0;
  443. }
  444. static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
  445. struct drm_display_mode *mode,
  446. struct drm_display_mode *adjusted_mode)
  447. {
  448. return true;
  449. }
  450. static void atombios_crtc_prepare(struct drm_crtc *crtc)
  451. {
  452. atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
  453. atombios_lock_crtc(crtc, 1);
  454. }
  455. static void atombios_crtc_commit(struct drm_crtc *crtc)
  456. {
  457. atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
  458. atombios_lock_crtc(crtc, 0);
  459. }
  460. static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
  461. .dpms = atombios_crtc_dpms,
  462. .mode_fixup = atombios_crtc_mode_fixup,
  463. .mode_set = atombios_crtc_mode_set,
  464. .mode_set_base = atombios_crtc_set_base,
  465. .prepare = atombios_crtc_prepare,
  466. .commit = atombios_crtc_commit,
  467. };
  468. void radeon_atombios_init_crtc(struct drm_device *dev,
  469. struct radeon_crtc *radeon_crtc)
  470. {
  471. if (radeon_crtc->crtc_id == 1)
  472. radeon_crtc->crtc_offset =
  473. AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
  474. drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
  475. }
  476. void radeon_init_disp_bw_avivo(struct drm_device *dev,
  477. struct drm_display_mode *mode1,
  478. uint32_t pixel_bytes1,
  479. struct drm_display_mode *mode2,
  480. uint32_t pixel_bytes2)
  481. {
  482. struct radeon_device *rdev = dev->dev_private;
  483. fixed20_12 min_mem_eff;
  484. fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff;
  485. fixed20_12 sclk_ff, mclk_ff;
  486. uint32_t dc_lb_memory_split, temp;
  487. min_mem_eff.full = rfixed_const_8(0);
  488. if (rdev->disp_priority == 2) {
  489. uint32_t mc_init_misc_lat_timer = 0;
  490. if (rdev->family == CHIP_RV515)
  491. mc_init_misc_lat_timer =
  492. RREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER);
  493. else if (rdev->family == CHIP_RS690)
  494. mc_init_misc_lat_timer =
  495. RREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER);
  496. mc_init_misc_lat_timer &=
  497. ~(R300_MC_DISP1R_INIT_LAT_MASK <<
  498. R300_MC_DISP1R_INIT_LAT_SHIFT);
  499. mc_init_misc_lat_timer &=
  500. ~(R300_MC_DISP0R_INIT_LAT_MASK <<
  501. R300_MC_DISP0R_INIT_LAT_SHIFT);
  502. if (mode2)
  503. mc_init_misc_lat_timer |=
  504. (1 << R300_MC_DISP1R_INIT_LAT_SHIFT);
  505. if (mode1)
  506. mc_init_misc_lat_timer |=
  507. (1 << R300_MC_DISP0R_INIT_LAT_SHIFT);
  508. if (rdev->family == CHIP_RV515)
  509. WREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER,
  510. mc_init_misc_lat_timer);
  511. else if (rdev->family == CHIP_RS690)
  512. WREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER,
  513. mc_init_misc_lat_timer);
  514. }
  515. /*
  516. * determine is there is enough bw for current mode
  517. */
  518. temp_ff.full = rfixed_const(100);
  519. mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
  520. mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
  521. sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
  522. sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
  523. temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
  524. temp_ff.full = rfixed_const(temp);
  525. mem_bw.full = rfixed_mul(mclk_ff, temp_ff);
  526. mem_bw.full = rfixed_mul(mem_bw, min_mem_eff);
  527. pix_clk.full = 0;
  528. pix_clk2.full = 0;
  529. peak_disp_bw.full = 0;
  530. if (mode1) {
  531. temp_ff.full = rfixed_const(1000);
  532. pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */
  533. pix_clk.full = rfixed_div(pix_clk, temp_ff);
  534. temp_ff.full = rfixed_const(pixel_bytes1);
  535. peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff);
  536. }
  537. if (mode2) {
  538. temp_ff.full = rfixed_const(1000);
  539. pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */
  540. pix_clk2.full = rfixed_div(pix_clk2, temp_ff);
  541. temp_ff.full = rfixed_const(pixel_bytes2);
  542. peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff);
  543. }
  544. if (peak_disp_bw.full >= mem_bw.full) {
  545. DRM_ERROR
  546. ("You may not have enough display bandwidth for current mode\n"
  547. "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
  548. printk("peak disp bw %d, mem_bw %d\n",
  549. rfixed_trunc(peak_disp_bw), rfixed_trunc(mem_bw));
  550. }
  551. /*
  552. * Line Buffer Setup
  553. * There is a single line buffer shared by both display controllers.
  554. * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between the display
  555. * controllers. The paritioning can either be done manually or via one of four
  556. * preset allocations specified in bits 1:0:
  557. * 0 - line buffer is divided in half and shared between each display controller
  558. * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
  559. * 2 - D1 gets the whole buffer
  560. * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
  561. * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual allocation mode.
  562. * In manual allocation mode, D1 always starts at 0, D1 end/2 is specified in bits
  563. * 14:4; D2 allocation follows D1.
  564. */
  565. /* is auto or manual better ? */
  566. dc_lb_memory_split =
  567. RREG32(AVIVO_DC_LB_MEMORY_SPLIT) & ~AVIVO_DC_LB_MEMORY_SPLIT_MASK;
  568. dc_lb_memory_split &= ~AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
  569. #if 1
  570. /* auto */
  571. if (mode1 && mode2) {
  572. if (mode1->hdisplay > mode2->hdisplay) {
  573. if (mode1->hdisplay > 2560)
  574. dc_lb_memory_split |=
  575. AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
  576. else
  577. dc_lb_memory_split |=
  578. AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
  579. } else if (mode2->hdisplay > mode1->hdisplay) {
  580. if (mode2->hdisplay > 2560)
  581. dc_lb_memory_split |=
  582. AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
  583. else
  584. dc_lb_memory_split |=
  585. AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
  586. } else
  587. dc_lb_memory_split |=
  588. AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
  589. } else if (mode1) {
  590. dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY;
  591. } else if (mode2) {
  592. dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
  593. }
  594. #else
  595. /* manual */
  596. dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
  597. dc_lb_memory_split &=
  598. ~(AVIVO_DC_LB_DISP1_END_ADR_MASK <<
  599. AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
  600. if (mode1) {
  601. dc_lb_memory_split |=
  602. ((((mode1->hdisplay / 2) + 64) & AVIVO_DC_LB_DISP1_END_ADR_MASK)
  603. << AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
  604. } else if (mode2) {
  605. dc_lb_memory_split |= (0 << AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
  606. }
  607. #endif
  608. WREG32(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split);
  609. }