psb_device.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /**************************************************************************
  3. * Copyright (c) 2011, Intel Corporation.
  4. * All Rights Reserved.
  5. *
  6. **************************************************************************/
  7. #include <drm/drm.h>
  8. #include <drm/drm_crtc_helper.h>
  9. #include "gma_device.h"
  10. #include "intel_bios.h"
  11. #include "psb_device.h"
  12. #include "psb_drv.h"
  13. #include "psb_intel_reg.h"
  14. #include "psb_reg.h"
  15. static int psb_output_init(struct drm_device *dev)
  16. {
  17. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  18. psb_intel_lvds_init(dev, &dev_priv->mode_dev);
  19. psb_intel_sdvo_init(dev, SDVOB);
  20. return 0;
  21. }
  22. /*
  23. * Poulsbo Backlight Interfaces
  24. */
  25. #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
  26. #define BLC_PWM_FREQ_CALC_CONSTANT 32
  27. #define MHz 1000000
  28. #define PSB_BLC_PWM_PRECISION_FACTOR 10
  29. #define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
  30. #define PSB_BLC_MIN_PWM_REG_FREQ 0x2
  31. #define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
  32. #define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
  33. static int psb_backlight_setup(struct drm_device *dev)
  34. {
  35. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  36. unsigned long core_clock;
  37. /* u32 bl_max_freq; */
  38. /* unsigned long value; */
  39. u16 bl_max_freq;
  40. uint32_t value;
  41. uint32_t blc_pwm_precision_factor;
  42. /* get bl_max_freq and pol from dev_priv*/
  43. if (!dev_priv->lvds_bl) {
  44. dev_err(dev->dev, "Has no valid LVDS backlight info\n");
  45. return -ENOENT;
  46. }
  47. bl_max_freq = dev_priv->lvds_bl->freq;
  48. blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
  49. core_clock = dev_priv->core_freq;
  50. value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
  51. value *= blc_pwm_precision_factor;
  52. value /= bl_max_freq;
  53. value /= blc_pwm_precision_factor;
  54. if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
  55. value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
  56. return -ERANGE;
  57. else {
  58. value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
  59. REG_WRITE(BLC_PWM_CTL,
  60. (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
  61. }
  62. psb_intel_lvds_set_brightness(dev, PSB_MAX_BRIGHTNESS);
  63. return 0;
  64. }
  65. /*
  66. * Provide the Poulsbo specific chip logic and low level methods
  67. * for power management
  68. */
  69. static void psb_init_pm(struct drm_device *dev)
  70. {
  71. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  72. u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
  73. gating &= ~3; /* Disable 2D clock gating */
  74. gating |= 1;
  75. PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
  76. PSB_RSGX32(PSB_CR_CLKGATECTL);
  77. }
  78. /**
  79. * psb_save_display_registers - save registers lost on suspend
  80. * @dev: our DRM device
  81. *
  82. * Save the state we need in order to be able to restore the interface
  83. * upon resume from suspend
  84. */
  85. static int psb_save_display_registers(struct drm_device *dev)
  86. {
  87. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  88. struct gma_connector *gma_connector;
  89. struct drm_crtc *crtc;
  90. struct drm_connector_list_iter conn_iter;
  91. struct drm_connector *connector;
  92. struct psb_state *regs = &dev_priv->regs.psb;
  93. /* Display arbitration control + watermarks */
  94. regs->saveDSPARB = PSB_RVDC32(DSPARB);
  95. regs->saveDSPFW1 = PSB_RVDC32(DSPFW1);
  96. regs->saveDSPFW2 = PSB_RVDC32(DSPFW2);
  97. regs->saveDSPFW3 = PSB_RVDC32(DSPFW3);
  98. regs->saveDSPFW4 = PSB_RVDC32(DSPFW4);
  99. regs->saveDSPFW5 = PSB_RVDC32(DSPFW5);
  100. regs->saveDSPFW6 = PSB_RVDC32(DSPFW6);
  101. regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
  102. /* Save crtc and output state */
  103. drm_modeset_lock_all(dev);
  104. list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  105. if (drm_helper_crtc_in_use(crtc))
  106. dev_priv->ops->save_crtc(crtc);
  107. }
  108. drm_connector_list_iter_begin(dev, &conn_iter);
  109. drm_for_each_connector_iter(connector, &conn_iter) {
  110. gma_connector = to_gma_connector(connector);
  111. if (gma_connector->save)
  112. gma_connector->save(connector);
  113. }
  114. drm_connector_list_iter_end(&conn_iter);
  115. drm_modeset_unlock_all(dev);
  116. return 0;
  117. }
  118. /**
  119. * psb_restore_display_registers - restore lost register state
  120. * @dev: our DRM device
  121. *
  122. * Restore register state that was lost during suspend and resume.
  123. */
  124. static int psb_restore_display_registers(struct drm_device *dev)
  125. {
  126. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  127. struct gma_connector *gma_connector;
  128. struct drm_crtc *crtc;
  129. struct drm_connector_list_iter conn_iter;
  130. struct drm_connector *connector;
  131. struct psb_state *regs = &dev_priv->regs.psb;
  132. /* Display arbitration + watermarks */
  133. PSB_WVDC32(regs->saveDSPARB, DSPARB);
  134. PSB_WVDC32(regs->saveDSPFW1, DSPFW1);
  135. PSB_WVDC32(regs->saveDSPFW2, DSPFW2);
  136. PSB_WVDC32(regs->saveDSPFW3, DSPFW3);
  137. PSB_WVDC32(regs->saveDSPFW4, DSPFW4);
  138. PSB_WVDC32(regs->saveDSPFW5, DSPFW5);
  139. PSB_WVDC32(regs->saveDSPFW6, DSPFW6);
  140. PSB_WVDC32(regs->saveCHICKENBIT, DSPCHICKENBIT);
  141. /*make sure VGA plane is off. it initializes to on after reset!*/
  142. PSB_WVDC32(0x80000000, VGACNTRL);
  143. drm_modeset_lock_all(dev);
  144. list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  145. if (drm_helper_crtc_in_use(crtc))
  146. dev_priv->ops->restore_crtc(crtc);
  147. drm_connector_list_iter_begin(dev, &conn_iter);
  148. drm_for_each_connector_iter(connector, &conn_iter) {
  149. gma_connector = to_gma_connector(connector);
  150. if (gma_connector->restore)
  151. gma_connector->restore(connector);
  152. }
  153. drm_connector_list_iter_end(&conn_iter);
  154. drm_modeset_unlock_all(dev);
  155. return 0;
  156. }
  157. static int psb_power_down(struct drm_device *dev)
  158. {
  159. return 0;
  160. }
  161. static int psb_power_up(struct drm_device *dev)
  162. {
  163. return 0;
  164. }
  165. /* Poulsbo */
  166. static const struct psb_offset psb_regmap[2] = {
  167. {
  168. .fp0 = FPA0,
  169. .fp1 = FPA1,
  170. .cntr = DSPACNTR,
  171. .conf = PIPEACONF,
  172. .src = PIPEASRC,
  173. .dpll = DPLL_A,
  174. .htotal = HTOTAL_A,
  175. .hblank = HBLANK_A,
  176. .hsync = HSYNC_A,
  177. .vtotal = VTOTAL_A,
  178. .vblank = VBLANK_A,
  179. .vsync = VSYNC_A,
  180. .stride = DSPASTRIDE,
  181. .size = DSPASIZE,
  182. .pos = DSPAPOS,
  183. .base = DSPABASE,
  184. .surf = DSPASURF,
  185. .addr = DSPABASE,
  186. .status = PIPEASTAT,
  187. .linoff = DSPALINOFF,
  188. .tileoff = DSPATILEOFF,
  189. .palette = PALETTE_A,
  190. },
  191. {
  192. .fp0 = FPB0,
  193. .fp1 = FPB1,
  194. .cntr = DSPBCNTR,
  195. .conf = PIPEBCONF,
  196. .src = PIPEBSRC,
  197. .dpll = DPLL_B,
  198. .htotal = HTOTAL_B,
  199. .hblank = HBLANK_B,
  200. .hsync = HSYNC_B,
  201. .vtotal = VTOTAL_B,
  202. .vblank = VBLANK_B,
  203. .vsync = VSYNC_B,
  204. .stride = DSPBSTRIDE,
  205. .size = DSPBSIZE,
  206. .pos = DSPBPOS,
  207. .base = DSPBBASE,
  208. .surf = DSPBSURF,
  209. .addr = DSPBBASE,
  210. .status = PIPEBSTAT,
  211. .linoff = DSPBLINOFF,
  212. .tileoff = DSPBTILEOFF,
  213. .palette = PALETTE_B,
  214. }
  215. };
  216. static int psb_chip_setup(struct drm_device *dev)
  217. {
  218. struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
  219. dev_priv->regmap = psb_regmap;
  220. gma_get_core_freq(dev);
  221. gma_intel_setup_gmbus(dev);
  222. psb_intel_opregion_init(dev);
  223. psb_intel_init_bios(dev);
  224. return 0;
  225. }
  226. static void psb_chip_teardown(struct drm_device *dev)
  227. {
  228. gma_intel_teardown_gmbus(dev);
  229. }
  230. const struct psb_ops psb_chip_ops = {
  231. .name = "Poulsbo",
  232. .pipes = 2,
  233. .crtcs = 2,
  234. .hdmi_mask = (1 << 0),
  235. .lvds_mask = (1 << 1),
  236. .sdvo_mask = (1 << 0),
  237. .cursor_needs_phys = 1,
  238. .sgx_offset = PSB_SGX_OFFSET,
  239. .chip_setup = psb_chip_setup,
  240. .chip_teardown = psb_chip_teardown,
  241. .crtc_helper = &psb_intel_helper_funcs,
  242. .clock_funcs = &psb_clock_funcs,
  243. .output_init = psb_output_init,
  244. .backlight_init = psb_backlight_setup,
  245. .backlight_set = psb_intel_lvds_set_brightness,
  246. .backlight_name = "psb-bl",
  247. .init_pm = psb_init_pm,
  248. .save_regs = psb_save_display_registers,
  249. .restore_regs = psb_restore_display_registers,
  250. .save_crtc = gma_crtc_save,
  251. .restore_crtc = gma_crtc_restore,
  252. .power_down = psb_power_down,
  253. .power_up = psb_power_up,
  254. };