intel_panel.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. /*
  2. * Copyright © 2006-2010 Intel Corporation
  3. * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
  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 (including the next
  13. * paragraph) shall be included in all copies or substantial portions of the
  14. * Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. *
  24. * Authors:
  25. * Eric Anholt <eric@anholt.net>
  26. * Dave Airlie <airlied@linux.ie>
  27. * Jesse Barnes <jesse.barnes@intel.com>
  28. * Chris Wilson <chris@chris-wilson.co.uk>
  29. */
  30. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  31. #include <linux/kernel.h>
  32. #include <linux/moduleparam.h>
  33. #include "intel_drv.h"
  34. void
  35. intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
  36. struct drm_display_mode *adjusted_mode)
  37. {
  38. drm_mode_copy(adjusted_mode, fixed_mode);
  39. drm_mode_set_crtcinfo(adjusted_mode, 0);
  40. }
  41. /**
  42. * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
  43. * @dev: drm device
  44. * @fixed_mode : panel native mode
  45. * @connector: LVDS/eDP connector
  46. *
  47. * Return downclock_avail
  48. * Find the reduced downclock for LVDS/eDP in EDID.
  49. */
  50. struct drm_display_mode *
  51. intel_find_panel_downclock(struct drm_device *dev,
  52. struct drm_display_mode *fixed_mode,
  53. struct drm_connector *connector)
  54. {
  55. struct drm_display_mode *scan, *tmp_mode;
  56. int temp_downclock;
  57. temp_downclock = fixed_mode->clock;
  58. tmp_mode = NULL;
  59. list_for_each_entry(scan, &connector->probed_modes, head) {
  60. /*
  61. * If one mode has the same resolution with the fixed_panel
  62. * mode while they have the different refresh rate, it means
  63. * that the reduced downclock is found. In such
  64. * case we can set the different FPx0/1 to dynamically select
  65. * between low and high frequency.
  66. */
  67. if (scan->hdisplay == fixed_mode->hdisplay &&
  68. scan->hsync_start == fixed_mode->hsync_start &&
  69. scan->hsync_end == fixed_mode->hsync_end &&
  70. scan->htotal == fixed_mode->htotal &&
  71. scan->vdisplay == fixed_mode->vdisplay &&
  72. scan->vsync_start == fixed_mode->vsync_start &&
  73. scan->vsync_end == fixed_mode->vsync_end &&
  74. scan->vtotal == fixed_mode->vtotal) {
  75. if (scan->clock < temp_downclock) {
  76. /*
  77. * The downclock is already found. But we
  78. * expect to find the lower downclock.
  79. */
  80. temp_downclock = scan->clock;
  81. tmp_mode = scan;
  82. }
  83. }
  84. }
  85. if (temp_downclock < fixed_mode->clock)
  86. return drm_mode_duplicate(dev, tmp_mode);
  87. else
  88. return NULL;
  89. }
  90. /* adjusted_mode has been preset to be the panel's fixed mode */
  91. void
  92. intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
  93. struct intel_crtc_state *pipe_config,
  94. int fitting_mode)
  95. {
  96. struct drm_display_mode *adjusted_mode;
  97. int x, y, width, height;
  98. adjusted_mode = &pipe_config->base.adjusted_mode;
  99. x = y = width = height = 0;
  100. /* Native modes don't need fitting */
  101. if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
  102. adjusted_mode->vdisplay == pipe_config->pipe_src_h)
  103. goto done;
  104. switch (fitting_mode) {
  105. case DRM_MODE_SCALE_CENTER:
  106. width = pipe_config->pipe_src_w;
  107. height = pipe_config->pipe_src_h;
  108. x = (adjusted_mode->hdisplay - width + 1)/2;
  109. y = (adjusted_mode->vdisplay - height + 1)/2;
  110. break;
  111. case DRM_MODE_SCALE_ASPECT:
  112. /* Scale but preserve the aspect ratio */
  113. {
  114. u32 scaled_width = adjusted_mode->hdisplay
  115. * pipe_config->pipe_src_h;
  116. u32 scaled_height = pipe_config->pipe_src_w
  117. * adjusted_mode->vdisplay;
  118. if (scaled_width > scaled_height) { /* pillar */
  119. width = scaled_height / pipe_config->pipe_src_h;
  120. if (width & 1)
  121. width++;
  122. x = (adjusted_mode->hdisplay - width + 1) / 2;
  123. y = 0;
  124. height = adjusted_mode->vdisplay;
  125. } else if (scaled_width < scaled_height) { /* letter */
  126. height = scaled_width / pipe_config->pipe_src_w;
  127. if (height & 1)
  128. height++;
  129. y = (adjusted_mode->vdisplay - height + 1) / 2;
  130. x = 0;
  131. width = adjusted_mode->hdisplay;
  132. } else {
  133. x = y = 0;
  134. width = adjusted_mode->hdisplay;
  135. height = adjusted_mode->vdisplay;
  136. }
  137. }
  138. break;
  139. case DRM_MODE_SCALE_FULLSCREEN:
  140. x = y = 0;
  141. width = adjusted_mode->hdisplay;
  142. height = adjusted_mode->vdisplay;
  143. break;
  144. default:
  145. WARN(1, "bad panel fit mode: %d\n", fitting_mode);
  146. return;
  147. }
  148. done:
  149. pipe_config->pch_pfit.pos = (x << 16) | y;
  150. pipe_config->pch_pfit.size = (width << 16) | height;
  151. pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
  152. }
  153. static void
  154. centre_horizontally(struct drm_display_mode *mode,
  155. int width)
  156. {
  157. u32 border, sync_pos, blank_width, sync_width;
  158. /* keep the hsync and hblank widths constant */
  159. sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
  160. blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
  161. sync_pos = (blank_width - sync_width + 1) / 2;
  162. border = (mode->hdisplay - width + 1) / 2;
  163. border += border & 1; /* make the border even */
  164. mode->crtc_hdisplay = width;
  165. mode->crtc_hblank_start = width + border;
  166. mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
  167. mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
  168. mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
  169. }
  170. static void
  171. centre_vertically(struct drm_display_mode *mode,
  172. int height)
  173. {
  174. u32 border, sync_pos, blank_width, sync_width;
  175. /* keep the vsync and vblank widths constant */
  176. sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
  177. blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
  178. sync_pos = (blank_width - sync_width + 1) / 2;
  179. border = (mode->vdisplay - height + 1) / 2;
  180. mode->crtc_vdisplay = height;
  181. mode->crtc_vblank_start = height + border;
  182. mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
  183. mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
  184. mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
  185. }
  186. static inline u32 panel_fitter_scaling(u32 source, u32 target)
  187. {
  188. /*
  189. * Floating point operation is not supported. So the FACTOR
  190. * is defined, which can avoid the floating point computation
  191. * when calculating the panel ratio.
  192. */
  193. #define ACCURACY 12
  194. #define FACTOR (1 << ACCURACY)
  195. u32 ratio = source * FACTOR / target;
  196. return (FACTOR * ratio + FACTOR/2) / FACTOR;
  197. }
  198. static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
  199. u32 *pfit_control)
  200. {
  201. struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
  202. u32 scaled_width = adjusted_mode->hdisplay *
  203. pipe_config->pipe_src_h;
  204. u32 scaled_height = pipe_config->pipe_src_w *
  205. adjusted_mode->vdisplay;
  206. /* 965+ is easy, it does everything in hw */
  207. if (scaled_width > scaled_height)
  208. *pfit_control |= PFIT_ENABLE |
  209. PFIT_SCALING_PILLAR;
  210. else if (scaled_width < scaled_height)
  211. *pfit_control |= PFIT_ENABLE |
  212. PFIT_SCALING_LETTER;
  213. else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w)
  214. *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
  215. }
  216. static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
  217. u32 *pfit_control, u32 *pfit_pgm_ratios,
  218. u32 *border)
  219. {
  220. struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
  221. u32 scaled_width = adjusted_mode->hdisplay *
  222. pipe_config->pipe_src_h;
  223. u32 scaled_height = pipe_config->pipe_src_w *
  224. adjusted_mode->vdisplay;
  225. u32 bits;
  226. /*
  227. * For earlier chips we have to calculate the scaling
  228. * ratio by hand and program it into the
  229. * PFIT_PGM_RATIO register
  230. */
  231. if (scaled_width > scaled_height) { /* pillar */
  232. centre_horizontally(adjusted_mode,
  233. scaled_height /
  234. pipe_config->pipe_src_h);
  235. *border = LVDS_BORDER_ENABLE;
  236. if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) {
  237. bits = panel_fitter_scaling(pipe_config->pipe_src_h,
  238. adjusted_mode->vdisplay);
  239. *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
  240. bits << PFIT_VERT_SCALE_SHIFT);
  241. *pfit_control |= (PFIT_ENABLE |
  242. VERT_INTERP_BILINEAR |
  243. HORIZ_INTERP_BILINEAR);
  244. }
  245. } else if (scaled_width < scaled_height) { /* letter */
  246. centre_vertically(adjusted_mode,
  247. scaled_width /
  248. pipe_config->pipe_src_w);
  249. *border = LVDS_BORDER_ENABLE;
  250. if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
  251. bits = panel_fitter_scaling(pipe_config->pipe_src_w,
  252. adjusted_mode->hdisplay);
  253. *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
  254. bits << PFIT_VERT_SCALE_SHIFT);
  255. *pfit_control |= (PFIT_ENABLE |
  256. VERT_INTERP_BILINEAR |
  257. HORIZ_INTERP_BILINEAR);
  258. }
  259. } else {
  260. /* Aspects match, Let hw scale both directions */
  261. *pfit_control |= (PFIT_ENABLE |
  262. VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
  263. VERT_INTERP_BILINEAR |
  264. HORIZ_INTERP_BILINEAR);
  265. }
  266. }
  267. void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
  268. struct intel_crtc_state *pipe_config,
  269. int fitting_mode)
  270. {
  271. struct drm_device *dev = intel_crtc->base.dev;
  272. u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
  273. struct drm_display_mode *adjusted_mode;
  274. adjusted_mode = &pipe_config->base.adjusted_mode;
  275. /* Native modes don't need fitting */
  276. if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
  277. adjusted_mode->vdisplay == pipe_config->pipe_src_h)
  278. goto out;
  279. switch (fitting_mode) {
  280. case DRM_MODE_SCALE_CENTER:
  281. /*
  282. * For centered modes, we have to calculate border widths &
  283. * heights and modify the values programmed into the CRTC.
  284. */
  285. centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
  286. centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
  287. border = LVDS_BORDER_ENABLE;
  288. break;
  289. case DRM_MODE_SCALE_ASPECT:
  290. /* Scale but preserve the aspect ratio */
  291. if (INTEL_INFO(dev)->gen >= 4)
  292. i965_scale_aspect(pipe_config, &pfit_control);
  293. else
  294. i9xx_scale_aspect(pipe_config, &pfit_control,
  295. &pfit_pgm_ratios, &border);
  296. break;
  297. case DRM_MODE_SCALE_FULLSCREEN:
  298. /*
  299. * Full scaling, even if it changes the aspect ratio.
  300. * Fortunately this is all done for us in hw.
  301. */
  302. if (pipe_config->pipe_src_h != adjusted_mode->vdisplay ||
  303. pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
  304. pfit_control |= PFIT_ENABLE;
  305. if (INTEL_INFO(dev)->gen >= 4)
  306. pfit_control |= PFIT_SCALING_AUTO;
  307. else
  308. pfit_control |= (VERT_AUTO_SCALE |
  309. VERT_INTERP_BILINEAR |
  310. HORIZ_AUTO_SCALE |
  311. HORIZ_INTERP_BILINEAR);
  312. }
  313. break;
  314. default:
  315. WARN(1, "bad panel fit mode: %d\n", fitting_mode);
  316. return;
  317. }
  318. /* 965+ wants fuzzy fitting */
  319. /* FIXME: handle multiple panels by failing gracefully */
  320. if (INTEL_INFO(dev)->gen >= 4)
  321. pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
  322. PFIT_FILTER_FUZZY);
  323. out:
  324. if ((pfit_control & PFIT_ENABLE) == 0) {
  325. pfit_control = 0;
  326. pfit_pgm_ratios = 0;
  327. }
  328. /* Make sure pre-965 set dither correctly for 18bpp panels. */
  329. if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
  330. pfit_control |= PANEL_8TO6_DITHER_ENABLE;
  331. pipe_config->gmch_pfit.control = pfit_control;
  332. pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
  333. pipe_config->gmch_pfit.lvds_border_bits = border;
  334. }
  335. enum drm_connector_status
  336. intel_panel_detect(struct drm_device *dev)
  337. {
  338. struct drm_i915_private *dev_priv = dev->dev_private;
  339. /* Assume that the BIOS does not lie through the OpRegion... */
  340. if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
  341. return ioread32(dev_priv->opregion.lid_state) & 0x1 ?
  342. connector_status_connected :
  343. connector_status_disconnected;
  344. }
  345. switch (i915.panel_ignore_lid) {
  346. case -2:
  347. return connector_status_connected;
  348. case -1:
  349. return connector_status_disconnected;
  350. default:
  351. return connector_status_unknown;
  352. }
  353. }
  354. /**
  355. * scale - scale values from one range to another
  356. *
  357. * @source_val: value in range [@source_min..@source_max]
  358. *
  359. * Return @source_val in range [@source_min..@source_max] scaled to range
  360. * [@target_min..@target_max].
  361. */
  362. static uint32_t scale(uint32_t source_val,
  363. uint32_t source_min, uint32_t source_max,
  364. uint32_t target_min, uint32_t target_max)
  365. {
  366. uint64_t target_val;
  367. WARN_ON(source_min > source_max);
  368. WARN_ON(target_min > target_max);
  369. /* defensive */
  370. source_val = clamp(source_val, source_min, source_max);
  371. /* avoid overflows */
  372. target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
  373. (target_max - target_min), source_max - source_min);
  374. target_val += target_min;
  375. return target_val;
  376. }
  377. /* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
  378. static inline u32 scale_user_to_hw(struct intel_connector *connector,
  379. u32 user_level, u32 user_max)
  380. {
  381. struct intel_panel *panel = &connector->panel;
  382. return scale(user_level, 0, user_max,
  383. panel->backlight.min, panel->backlight.max);
  384. }
  385. /* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
  386. * to [hw_min..hw_max]. */
  387. static inline u32 clamp_user_to_hw(struct intel_connector *connector,
  388. u32 user_level, u32 user_max)
  389. {
  390. struct intel_panel *panel = &connector->panel;
  391. u32 hw_level;
  392. hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
  393. hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
  394. return hw_level;
  395. }
  396. /* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
  397. static inline u32 scale_hw_to_user(struct intel_connector *connector,
  398. u32 hw_level, u32 user_max)
  399. {
  400. struct intel_panel *panel = &connector->panel;
  401. return scale(hw_level, panel->backlight.min, panel->backlight.max,
  402. 0, user_max);
  403. }
  404. static u32 intel_panel_compute_brightness(struct intel_connector *connector,
  405. u32 val)
  406. {
  407. struct drm_device *dev = connector->base.dev;
  408. struct drm_i915_private *dev_priv = dev->dev_private;
  409. struct intel_panel *panel = &connector->panel;
  410. WARN_ON(panel->backlight.max == 0);
  411. if (i915.invert_brightness < 0)
  412. return val;
  413. if (i915.invert_brightness > 0 ||
  414. dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
  415. return panel->backlight.max - val;
  416. }
  417. return val;
  418. }
  419. static u32 bdw_get_backlight(struct intel_connector *connector)
  420. {
  421. struct drm_device *dev = connector->base.dev;
  422. struct drm_i915_private *dev_priv = dev->dev_private;
  423. return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
  424. }
  425. static u32 pch_get_backlight(struct intel_connector *connector)
  426. {
  427. struct drm_device *dev = connector->base.dev;
  428. struct drm_i915_private *dev_priv = dev->dev_private;
  429. return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
  430. }
  431. static u32 i9xx_get_backlight(struct intel_connector *connector)
  432. {
  433. struct drm_device *dev = connector->base.dev;
  434. struct drm_i915_private *dev_priv = dev->dev_private;
  435. struct intel_panel *panel = &connector->panel;
  436. u32 val;
  437. val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
  438. if (INTEL_INFO(dev)->gen < 4)
  439. val >>= 1;
  440. if (panel->backlight.combination_mode) {
  441. u8 lbpc;
  442. pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
  443. val *= lbpc;
  444. }
  445. return val;
  446. }
  447. static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
  448. {
  449. struct drm_i915_private *dev_priv = dev->dev_private;
  450. if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
  451. return 0;
  452. return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
  453. }
  454. static u32 vlv_get_backlight(struct intel_connector *connector)
  455. {
  456. struct drm_device *dev = connector->base.dev;
  457. enum pipe pipe = intel_get_pipe_from_connector(connector);
  458. return _vlv_get_backlight(dev, pipe);
  459. }
  460. static u32 intel_panel_get_backlight(struct intel_connector *connector)
  461. {
  462. struct drm_device *dev = connector->base.dev;
  463. struct drm_i915_private *dev_priv = dev->dev_private;
  464. struct intel_panel *panel = &connector->panel;
  465. u32 val = 0;
  466. mutex_lock(&dev_priv->backlight_lock);
  467. if (panel->backlight.enabled) {
  468. val = dev_priv->display.get_backlight(connector);
  469. val = intel_panel_compute_brightness(connector, val);
  470. }
  471. mutex_unlock(&dev_priv->backlight_lock);
  472. DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
  473. return val;
  474. }
  475. static void bdw_set_backlight(struct intel_connector *connector, u32 level)
  476. {
  477. struct drm_device *dev = connector->base.dev;
  478. struct drm_i915_private *dev_priv = dev->dev_private;
  479. u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
  480. I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
  481. }
  482. static void pch_set_backlight(struct intel_connector *connector, u32 level)
  483. {
  484. struct drm_device *dev = connector->base.dev;
  485. struct drm_i915_private *dev_priv = dev->dev_private;
  486. u32 tmp;
  487. tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
  488. I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
  489. }
  490. static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
  491. {
  492. struct drm_device *dev = connector->base.dev;
  493. struct drm_i915_private *dev_priv = dev->dev_private;
  494. struct intel_panel *panel = &connector->panel;
  495. u32 tmp, mask;
  496. WARN_ON(panel->backlight.max == 0);
  497. if (panel->backlight.combination_mode) {
  498. u8 lbpc;
  499. lbpc = level * 0xfe / panel->backlight.max + 1;
  500. level /= lbpc;
  501. pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
  502. }
  503. if (IS_GEN4(dev)) {
  504. mask = BACKLIGHT_DUTY_CYCLE_MASK;
  505. } else {
  506. level <<= 1;
  507. mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
  508. }
  509. tmp = I915_READ(BLC_PWM_CTL) & ~mask;
  510. I915_WRITE(BLC_PWM_CTL, tmp | level);
  511. }
  512. static void vlv_set_backlight(struct intel_connector *connector, u32 level)
  513. {
  514. struct drm_device *dev = connector->base.dev;
  515. struct drm_i915_private *dev_priv = dev->dev_private;
  516. enum pipe pipe = intel_get_pipe_from_connector(connector);
  517. u32 tmp;
  518. if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
  519. return;
  520. tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
  521. I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
  522. }
  523. static void
  524. intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
  525. {
  526. struct drm_device *dev = connector->base.dev;
  527. struct drm_i915_private *dev_priv = dev->dev_private;
  528. DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
  529. level = intel_panel_compute_brightness(connector, level);
  530. dev_priv->display.set_backlight(connector, level);
  531. }
  532. /* set backlight brightness to level in range [0..max], scaling wrt hw min */
  533. static void intel_panel_set_backlight(struct intel_connector *connector,
  534. u32 user_level, u32 user_max)
  535. {
  536. struct drm_device *dev = connector->base.dev;
  537. struct drm_i915_private *dev_priv = dev->dev_private;
  538. struct intel_panel *panel = &connector->panel;
  539. u32 hw_level;
  540. if (!panel->backlight.present)
  541. return;
  542. mutex_lock(&dev_priv->backlight_lock);
  543. WARN_ON(panel->backlight.max == 0);
  544. hw_level = scale_user_to_hw(connector, user_level, user_max);
  545. panel->backlight.level = hw_level;
  546. if (panel->backlight.enabled)
  547. intel_panel_actually_set_backlight(connector, hw_level);
  548. mutex_unlock(&dev_priv->backlight_lock);
  549. }
  550. /* set backlight brightness to level in range [0..max], assuming hw min is
  551. * respected.
  552. */
  553. void intel_panel_set_backlight_acpi(struct intel_connector *connector,
  554. u32 user_level, u32 user_max)
  555. {
  556. struct drm_device *dev = connector->base.dev;
  557. struct drm_i915_private *dev_priv = dev->dev_private;
  558. struct intel_panel *panel = &connector->panel;
  559. enum pipe pipe = intel_get_pipe_from_connector(connector);
  560. u32 hw_level;
  561. /*
  562. * INVALID_PIPE may occur during driver init because
  563. * connection_mutex isn't held across the entire backlight
  564. * setup + modeset readout, and the BIOS can issue the
  565. * requests at any time.
  566. */
  567. if (!panel->backlight.present || pipe == INVALID_PIPE)
  568. return;
  569. mutex_lock(&dev_priv->backlight_lock);
  570. WARN_ON(panel->backlight.max == 0);
  571. hw_level = clamp_user_to_hw(connector, user_level, user_max);
  572. panel->backlight.level = hw_level;
  573. if (panel->backlight.device)
  574. panel->backlight.device->props.brightness =
  575. scale_hw_to_user(connector,
  576. panel->backlight.level,
  577. panel->backlight.device->props.max_brightness);
  578. if (panel->backlight.enabled)
  579. intel_panel_actually_set_backlight(connector, hw_level);
  580. mutex_unlock(&dev_priv->backlight_lock);
  581. }
  582. static void pch_disable_backlight(struct intel_connector *connector)
  583. {
  584. struct drm_device *dev = connector->base.dev;
  585. struct drm_i915_private *dev_priv = dev->dev_private;
  586. u32 tmp;
  587. intel_panel_actually_set_backlight(connector, 0);
  588. tmp = I915_READ(BLC_PWM_CPU_CTL2);
  589. I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
  590. tmp = I915_READ(BLC_PWM_PCH_CTL1);
  591. I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
  592. }
  593. static void i9xx_disable_backlight(struct intel_connector *connector)
  594. {
  595. intel_panel_actually_set_backlight(connector, 0);
  596. }
  597. static void i965_disable_backlight(struct intel_connector *connector)
  598. {
  599. struct drm_device *dev = connector->base.dev;
  600. struct drm_i915_private *dev_priv = dev->dev_private;
  601. u32 tmp;
  602. intel_panel_actually_set_backlight(connector, 0);
  603. tmp = I915_READ(BLC_PWM_CTL2);
  604. I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
  605. }
  606. static void vlv_disable_backlight(struct intel_connector *connector)
  607. {
  608. struct drm_device *dev = connector->base.dev;
  609. struct drm_i915_private *dev_priv = dev->dev_private;
  610. enum pipe pipe = intel_get_pipe_from_connector(connector);
  611. u32 tmp;
  612. if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
  613. return;
  614. intel_panel_actually_set_backlight(connector, 0);
  615. tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
  616. I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
  617. }
  618. void intel_panel_disable_backlight(struct intel_connector *connector)
  619. {
  620. struct drm_device *dev = connector->base.dev;
  621. struct drm_i915_private *dev_priv = dev->dev_private;
  622. struct intel_panel *panel = &connector->panel;
  623. if (!panel->backlight.present)
  624. return;
  625. /*
  626. * Do not disable backlight on the vgaswitcheroo path. When switching
  627. * away from i915, the other client may depend on i915 to handle the
  628. * backlight. This will leave the backlight on unnecessarily when
  629. * another client is not activated.
  630. */
  631. if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
  632. DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
  633. return;
  634. }
  635. mutex_lock(&dev_priv->backlight_lock);
  636. if (panel->backlight.device)
  637. panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
  638. panel->backlight.enabled = false;
  639. dev_priv->display.disable_backlight(connector);
  640. mutex_unlock(&dev_priv->backlight_lock);
  641. }
  642. static void bdw_enable_backlight(struct intel_connector *connector)
  643. {
  644. struct drm_device *dev = connector->base.dev;
  645. struct drm_i915_private *dev_priv = dev->dev_private;
  646. struct intel_panel *panel = &connector->panel;
  647. u32 pch_ctl1, pch_ctl2;
  648. pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
  649. if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
  650. DRM_DEBUG_KMS("pch backlight already enabled\n");
  651. pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
  652. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
  653. }
  654. pch_ctl2 = panel->backlight.max << 16;
  655. I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
  656. pch_ctl1 = 0;
  657. if (panel->backlight.active_low_pwm)
  658. pch_ctl1 |= BLM_PCH_POLARITY;
  659. /* After LPT, override is the default. */
  660. if (HAS_PCH_LPT(dev_priv))
  661. pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
  662. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
  663. POSTING_READ(BLC_PWM_PCH_CTL1);
  664. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
  665. /* This won't stick until the above enable. */
  666. intel_panel_actually_set_backlight(connector, panel->backlight.level);
  667. }
  668. static void pch_enable_backlight(struct intel_connector *connector)
  669. {
  670. struct drm_device *dev = connector->base.dev;
  671. struct drm_i915_private *dev_priv = dev->dev_private;
  672. struct intel_panel *panel = &connector->panel;
  673. enum pipe pipe = intel_get_pipe_from_connector(connector);
  674. enum transcoder cpu_transcoder =
  675. intel_pipe_to_cpu_transcoder(dev_priv, pipe);
  676. u32 cpu_ctl2, pch_ctl1, pch_ctl2;
  677. cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
  678. if (cpu_ctl2 & BLM_PWM_ENABLE) {
  679. DRM_DEBUG_KMS("cpu backlight already enabled\n");
  680. cpu_ctl2 &= ~BLM_PWM_ENABLE;
  681. I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
  682. }
  683. pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
  684. if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
  685. DRM_DEBUG_KMS("pch backlight already enabled\n");
  686. pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
  687. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
  688. }
  689. if (cpu_transcoder == TRANSCODER_EDP)
  690. cpu_ctl2 = BLM_TRANSCODER_EDP;
  691. else
  692. cpu_ctl2 = BLM_PIPE(cpu_transcoder);
  693. I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
  694. POSTING_READ(BLC_PWM_CPU_CTL2);
  695. I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
  696. /* This won't stick until the above enable. */
  697. intel_panel_actually_set_backlight(connector, panel->backlight.level);
  698. pch_ctl2 = panel->backlight.max << 16;
  699. I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
  700. pch_ctl1 = 0;
  701. if (panel->backlight.active_low_pwm)
  702. pch_ctl1 |= BLM_PCH_POLARITY;
  703. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
  704. POSTING_READ(BLC_PWM_PCH_CTL1);
  705. I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
  706. }
  707. static void i9xx_enable_backlight(struct intel_connector *connector)
  708. {
  709. struct drm_device *dev = connector->base.dev;
  710. struct drm_i915_private *dev_priv = dev->dev_private;
  711. struct intel_panel *panel = &connector->panel;
  712. u32 ctl, freq;
  713. ctl = I915_READ(BLC_PWM_CTL);
  714. if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
  715. DRM_DEBUG_KMS("backlight already enabled\n");
  716. I915_WRITE(BLC_PWM_CTL, 0);
  717. }
  718. freq = panel->backlight.max;
  719. if (panel->backlight.combination_mode)
  720. freq /= 0xff;
  721. ctl = freq << 17;
  722. if (panel->backlight.combination_mode)
  723. ctl |= BLM_LEGACY_MODE;
  724. if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
  725. ctl |= BLM_POLARITY_PNV;
  726. I915_WRITE(BLC_PWM_CTL, ctl);
  727. POSTING_READ(BLC_PWM_CTL);
  728. /* XXX: combine this into above write? */
  729. intel_panel_actually_set_backlight(connector, panel->backlight.level);
  730. }
  731. static void i965_enable_backlight(struct intel_connector *connector)
  732. {
  733. struct drm_device *dev = connector->base.dev;
  734. struct drm_i915_private *dev_priv = dev->dev_private;
  735. struct intel_panel *panel = &connector->panel;
  736. enum pipe pipe = intel_get_pipe_from_connector(connector);
  737. u32 ctl, ctl2, freq;
  738. ctl2 = I915_READ(BLC_PWM_CTL2);
  739. if (ctl2 & BLM_PWM_ENABLE) {
  740. DRM_DEBUG_KMS("backlight already enabled\n");
  741. ctl2 &= ~BLM_PWM_ENABLE;
  742. I915_WRITE(BLC_PWM_CTL2, ctl2);
  743. }
  744. freq = panel->backlight.max;
  745. if (panel->backlight.combination_mode)
  746. freq /= 0xff;
  747. ctl = freq << 16;
  748. I915_WRITE(BLC_PWM_CTL, ctl);
  749. ctl2 = BLM_PIPE(pipe);
  750. if (panel->backlight.combination_mode)
  751. ctl2 |= BLM_COMBINATION_MODE;
  752. if (panel->backlight.active_low_pwm)
  753. ctl2 |= BLM_POLARITY_I965;
  754. I915_WRITE(BLC_PWM_CTL2, ctl2);
  755. POSTING_READ(BLC_PWM_CTL2);
  756. I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
  757. intel_panel_actually_set_backlight(connector, panel->backlight.level);
  758. }
  759. static void vlv_enable_backlight(struct intel_connector *connector)
  760. {
  761. struct drm_device *dev = connector->base.dev;
  762. struct drm_i915_private *dev_priv = dev->dev_private;
  763. struct intel_panel *panel = &connector->panel;
  764. enum pipe pipe = intel_get_pipe_from_connector(connector);
  765. u32 ctl, ctl2;
  766. if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
  767. return;
  768. ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
  769. if (ctl2 & BLM_PWM_ENABLE) {
  770. DRM_DEBUG_KMS("backlight already enabled\n");
  771. ctl2 &= ~BLM_PWM_ENABLE;
  772. I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
  773. }
  774. ctl = panel->backlight.max << 16;
  775. I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
  776. /* XXX: combine this into above write? */
  777. intel_panel_actually_set_backlight(connector, panel->backlight.level);
  778. ctl2 = 0;
  779. if (panel->backlight.active_low_pwm)
  780. ctl2 |= BLM_POLARITY_I965;
  781. I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
  782. POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
  783. I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
  784. }
  785. void intel_panel_enable_backlight(struct intel_connector *connector)
  786. {
  787. struct drm_device *dev = connector->base.dev;
  788. struct drm_i915_private *dev_priv = dev->dev_private;
  789. struct intel_panel *panel = &connector->panel;
  790. enum pipe pipe = intel_get_pipe_from_connector(connector);
  791. if (!panel->backlight.present)
  792. return;
  793. DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
  794. mutex_lock(&dev_priv->backlight_lock);
  795. WARN_ON(panel->backlight.max == 0);
  796. if (panel->backlight.level <= panel->backlight.min) {
  797. panel->backlight.level = panel->backlight.max;
  798. if (panel->backlight.device)
  799. panel->backlight.device->props.brightness =
  800. scale_hw_to_user(connector,
  801. panel->backlight.level,
  802. panel->backlight.device->props.max_brightness);
  803. }
  804. dev_priv->display.enable_backlight(connector);
  805. panel->backlight.enabled = true;
  806. if (panel->backlight.device)
  807. panel->backlight.device->props.power = FB_BLANK_UNBLANK;
  808. mutex_unlock(&dev_priv->backlight_lock);
  809. }
  810. #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
  811. static int intel_backlight_device_update_status(struct backlight_device *bd)
  812. {
  813. struct intel_connector *connector = bl_get_data(bd);
  814. struct intel_panel *panel = &connector->panel;
  815. struct drm_device *dev = connector->base.dev;
  816. drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
  817. DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
  818. bd->props.brightness, bd->props.max_brightness);
  819. intel_panel_set_backlight(connector, bd->props.brightness,
  820. bd->props.max_brightness);
  821. /*
  822. * Allow flipping bl_power as a sub-state of enabled. Sadly the
  823. * backlight class device does not make it easy to to differentiate
  824. * between callbacks for brightness and bl_power, so our backlight_power
  825. * callback needs to take this into account.
  826. */
  827. if (panel->backlight.enabled) {
  828. if (panel->backlight_power) {
  829. bool enable = bd->props.power == FB_BLANK_UNBLANK &&
  830. bd->props.brightness != 0;
  831. panel->backlight_power(connector, enable);
  832. }
  833. } else {
  834. bd->props.power = FB_BLANK_POWERDOWN;
  835. }
  836. drm_modeset_unlock(&dev->mode_config.connection_mutex);
  837. return 0;
  838. }
  839. static int intel_backlight_device_get_brightness(struct backlight_device *bd)
  840. {
  841. struct intel_connector *connector = bl_get_data(bd);
  842. struct drm_device *dev = connector->base.dev;
  843. struct drm_i915_private *dev_priv = dev->dev_private;
  844. u32 hw_level;
  845. int ret;
  846. intel_runtime_pm_get(dev_priv);
  847. drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
  848. hw_level = intel_panel_get_backlight(connector);
  849. ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness);
  850. drm_modeset_unlock(&dev->mode_config.connection_mutex);
  851. intel_runtime_pm_put(dev_priv);
  852. return ret;
  853. }
  854. static const struct backlight_ops intel_backlight_device_ops = {
  855. .update_status = intel_backlight_device_update_status,
  856. .get_brightness = intel_backlight_device_get_brightness,
  857. };
  858. static int intel_backlight_device_register(struct intel_connector *connector)
  859. {
  860. struct intel_panel *panel = &connector->panel;
  861. struct backlight_properties props;
  862. if (WARN_ON(panel->backlight.device))
  863. return -ENODEV;
  864. if (!panel->backlight.present)
  865. return 0;
  866. WARN_ON(panel->backlight.max == 0);
  867. memset(&props, 0, sizeof(props));
  868. props.type = BACKLIGHT_RAW;
  869. /*
  870. * Note: Everything should work even if the backlight device max
  871. * presented to the userspace is arbitrarily chosen.
  872. */
  873. props.max_brightness = panel->backlight.max;
  874. props.brightness = scale_hw_to_user(connector,
  875. panel->backlight.level,
  876. props.max_brightness);
  877. if (panel->backlight.enabled)
  878. props.power = FB_BLANK_UNBLANK;
  879. else
  880. props.power = FB_BLANK_POWERDOWN;
  881. /*
  882. * Note: using the same name independent of the connector prevents
  883. * registration of multiple backlight devices in the driver.
  884. */
  885. panel->backlight.device =
  886. backlight_device_register("intel_backlight",
  887. connector->base.kdev,
  888. connector,
  889. &intel_backlight_device_ops, &props);
  890. if (IS_ERR(panel->backlight.device)) {
  891. DRM_ERROR("Failed to register backlight: %ld\n",
  892. PTR_ERR(panel->backlight.device));
  893. panel->backlight.device = NULL;
  894. return -ENODEV;
  895. }
  896. DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
  897. connector->base.name);
  898. return 0;
  899. }
  900. static void intel_backlight_device_unregister(struct intel_connector *connector)
  901. {
  902. struct intel_panel *panel = &connector->panel;
  903. if (panel->backlight.device) {
  904. backlight_device_unregister(panel->backlight.device);
  905. panel->backlight.device = NULL;
  906. }
  907. }
  908. #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
  909. static int intel_backlight_device_register(struct intel_connector *connector)
  910. {
  911. return 0;
  912. }
  913. static void intel_backlight_device_unregister(struct intel_connector *connector)
  914. {
  915. }
  916. #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
  917. /*
  918. * Note: The setup hooks can't assume pipe is set!
  919. *
  920. * XXX: Query mode clock or hardware clock and program PWM modulation frequency
  921. * appropriately when it's 0. Use VBT and/or sane defaults.
  922. */
  923. static u32 get_backlight_min_vbt(struct intel_connector *connector)
  924. {
  925. struct drm_device *dev = connector->base.dev;
  926. struct drm_i915_private *dev_priv = dev->dev_private;
  927. struct intel_panel *panel = &connector->panel;
  928. int min;
  929. WARN_ON(panel->backlight.max == 0);
  930. /*
  931. * XXX: If the vbt value is 255, it makes min equal to max, which leads
  932. * to problems. There are such machines out there. Either our
  933. * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
  934. * against this by letting the minimum be at most (arbitrarily chosen)
  935. * 25% of the max.
  936. */
  937. min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
  938. if (min != dev_priv->vbt.backlight.min_brightness) {
  939. DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n",
  940. dev_priv->vbt.backlight.min_brightness, min);
  941. }
  942. /* vbt value is a coefficient in range [0..255] */
  943. return scale(min, 0, 255, 0, panel->backlight.max);
  944. }
  945. static int bdw_setup_backlight(struct intel_connector *connector, enum pipe unused)
  946. {
  947. struct drm_device *dev = connector->base.dev;
  948. struct drm_i915_private *dev_priv = dev->dev_private;
  949. struct intel_panel *panel = &connector->panel;
  950. u32 pch_ctl1, pch_ctl2, val;
  951. pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
  952. panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
  953. pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
  954. panel->backlight.max = pch_ctl2 >> 16;
  955. if (!panel->backlight.max)
  956. return -ENODEV;
  957. panel->backlight.min = get_backlight_min_vbt(connector);
  958. val = bdw_get_backlight(connector);
  959. panel->backlight.level = intel_panel_compute_brightness(connector, val);
  960. panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
  961. panel->backlight.level != 0;
  962. return 0;
  963. }
  964. static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
  965. {
  966. struct drm_device *dev = connector->base.dev;
  967. struct drm_i915_private *dev_priv = dev->dev_private;
  968. struct intel_panel *panel = &connector->panel;
  969. u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
  970. pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
  971. panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
  972. pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
  973. panel->backlight.max = pch_ctl2 >> 16;
  974. if (!panel->backlight.max)
  975. return -ENODEV;
  976. panel->backlight.min = get_backlight_min_vbt(connector);
  977. val = pch_get_backlight(connector);
  978. panel->backlight.level = intel_panel_compute_brightness(connector, val);
  979. cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
  980. panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
  981. (pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
  982. return 0;
  983. }
  984. static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
  985. {
  986. struct drm_device *dev = connector->base.dev;
  987. struct drm_i915_private *dev_priv = dev->dev_private;
  988. struct intel_panel *panel = &connector->panel;
  989. u32 ctl, val;
  990. ctl = I915_READ(BLC_PWM_CTL);
  991. if (IS_GEN2(dev) || IS_I915GM(dev) || IS_I945GM(dev))
  992. panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
  993. if (IS_PINEVIEW(dev))
  994. panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
  995. panel->backlight.max = ctl >> 17;
  996. if (panel->backlight.combination_mode)
  997. panel->backlight.max *= 0xff;
  998. if (!panel->backlight.max)
  999. return -ENODEV;
  1000. panel->backlight.min = get_backlight_min_vbt(connector);
  1001. val = i9xx_get_backlight(connector);
  1002. panel->backlight.level = intel_panel_compute_brightness(connector, val);
  1003. panel->backlight.enabled = panel->backlight.level != 0;
  1004. return 0;
  1005. }
  1006. static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
  1007. {
  1008. struct drm_device *dev = connector->base.dev;
  1009. struct drm_i915_private *dev_priv = dev->dev_private;
  1010. struct intel_panel *panel = &connector->panel;
  1011. u32 ctl, ctl2, val;
  1012. ctl2 = I915_READ(BLC_PWM_CTL2);
  1013. panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
  1014. panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
  1015. ctl = I915_READ(BLC_PWM_CTL);
  1016. panel->backlight.max = ctl >> 16;
  1017. if (panel->backlight.combination_mode)
  1018. panel->backlight.max *= 0xff;
  1019. if (!panel->backlight.max)
  1020. return -ENODEV;
  1021. panel->backlight.min = get_backlight_min_vbt(connector);
  1022. val = i9xx_get_backlight(connector);
  1023. panel->backlight.level = intel_panel_compute_brightness(connector, val);
  1024. panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
  1025. panel->backlight.level != 0;
  1026. return 0;
  1027. }
  1028. static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
  1029. {
  1030. struct drm_device *dev = connector->base.dev;
  1031. struct drm_i915_private *dev_priv = dev->dev_private;
  1032. struct intel_panel *panel = &connector->panel;
  1033. enum pipe p;
  1034. u32 ctl, ctl2, val;
  1035. for_each_pipe(dev_priv, p) {
  1036. u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(p));
  1037. /* Skip if the modulation freq is already set */
  1038. if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
  1039. continue;
  1040. cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
  1041. I915_WRITE(VLV_BLC_PWM_CTL(p), (0xf42 << 16) |
  1042. cur_val);
  1043. }
  1044. if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
  1045. return -ENODEV;
  1046. ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
  1047. panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
  1048. ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
  1049. panel->backlight.max = ctl >> 16;
  1050. if (!panel->backlight.max)
  1051. return -ENODEV;
  1052. panel->backlight.min = get_backlight_min_vbt(connector);
  1053. val = _vlv_get_backlight(dev, pipe);
  1054. panel->backlight.level = intel_panel_compute_brightness(connector, val);
  1055. panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
  1056. panel->backlight.level != 0;
  1057. return 0;
  1058. }
  1059. int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
  1060. {
  1061. struct drm_device *dev = connector->dev;
  1062. struct drm_i915_private *dev_priv = dev->dev_private;
  1063. struct intel_connector *intel_connector = to_intel_connector(connector);
  1064. struct intel_panel *panel = &intel_connector->panel;
  1065. int ret;
  1066. if (!dev_priv->vbt.backlight.present) {
  1067. if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
  1068. DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
  1069. } else {
  1070. DRM_DEBUG_KMS("no backlight present per VBT\n");
  1071. return 0;
  1072. }
  1073. }
  1074. /* set level and max in panel struct */
  1075. mutex_lock(&dev_priv->backlight_lock);
  1076. ret = dev_priv->display.setup_backlight(intel_connector, pipe);
  1077. mutex_unlock(&dev_priv->backlight_lock);
  1078. if (ret) {
  1079. DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
  1080. connector->name);
  1081. return ret;
  1082. }
  1083. panel->backlight.present = true;
  1084. DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n",
  1085. connector->name,
  1086. panel->backlight.enabled ? "enabled" : "disabled",
  1087. panel->backlight.level, panel->backlight.max);
  1088. return 0;
  1089. }
  1090. void intel_panel_destroy_backlight(struct drm_connector *connector)
  1091. {
  1092. struct intel_connector *intel_connector = to_intel_connector(connector);
  1093. struct intel_panel *panel = &intel_connector->panel;
  1094. panel->backlight.present = false;
  1095. }
  1096. /* Set up chip specific backlight functions */
  1097. void intel_panel_init_backlight_funcs(struct drm_device *dev)
  1098. {
  1099. struct drm_i915_private *dev_priv = dev->dev_private;
  1100. if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
  1101. dev_priv->display.setup_backlight = bdw_setup_backlight;
  1102. dev_priv->display.enable_backlight = bdw_enable_backlight;
  1103. dev_priv->display.disable_backlight = pch_disable_backlight;
  1104. dev_priv->display.set_backlight = bdw_set_backlight;
  1105. dev_priv->display.get_backlight = bdw_get_backlight;
  1106. } else if (HAS_PCH_SPLIT(dev)) {
  1107. dev_priv->display.setup_backlight = pch_setup_backlight;
  1108. dev_priv->display.enable_backlight = pch_enable_backlight;
  1109. dev_priv->display.disable_backlight = pch_disable_backlight;
  1110. dev_priv->display.set_backlight = pch_set_backlight;
  1111. dev_priv->display.get_backlight = pch_get_backlight;
  1112. } else if (IS_VALLEYVIEW(dev)) {
  1113. dev_priv->display.setup_backlight = vlv_setup_backlight;
  1114. dev_priv->display.enable_backlight = vlv_enable_backlight;
  1115. dev_priv->display.disable_backlight = vlv_disable_backlight;
  1116. dev_priv->display.set_backlight = vlv_set_backlight;
  1117. dev_priv->display.get_backlight = vlv_get_backlight;
  1118. } else if (IS_GEN4(dev)) {
  1119. dev_priv->display.setup_backlight = i965_setup_backlight;
  1120. dev_priv->display.enable_backlight = i965_enable_backlight;
  1121. dev_priv->display.disable_backlight = i965_disable_backlight;
  1122. dev_priv->display.set_backlight = i9xx_set_backlight;
  1123. dev_priv->display.get_backlight = i9xx_get_backlight;
  1124. } else {
  1125. dev_priv->display.setup_backlight = i9xx_setup_backlight;
  1126. dev_priv->display.enable_backlight = i9xx_enable_backlight;
  1127. dev_priv->display.disable_backlight = i9xx_disable_backlight;
  1128. dev_priv->display.set_backlight = i9xx_set_backlight;
  1129. dev_priv->display.get_backlight = i9xx_get_backlight;
  1130. }
  1131. }
  1132. int intel_panel_init(struct intel_panel *panel,
  1133. struct drm_display_mode *fixed_mode,
  1134. struct drm_display_mode *downclock_mode)
  1135. {
  1136. panel->fixed_mode = fixed_mode;
  1137. panel->downclock_mode = downclock_mode;
  1138. return 0;
  1139. }
  1140. void intel_panel_fini(struct intel_panel *panel)
  1141. {
  1142. struct intel_connector *intel_connector =
  1143. container_of(panel, struct intel_connector, panel);
  1144. if (panel->fixed_mode)
  1145. drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
  1146. if (panel->downclock_mode)
  1147. drm_mode_destroy(intel_connector->base.dev,
  1148. panel->downclock_mode);
  1149. }
  1150. void intel_backlight_register(struct drm_device *dev)
  1151. {
  1152. struct intel_connector *connector;
  1153. list_for_each_entry(connector, &dev->mode_config.connector_list, base.head)
  1154. intel_backlight_device_register(connector);
  1155. }
  1156. void intel_backlight_unregister(struct drm_device *dev)
  1157. {
  1158. struct intel_connector *connector;
  1159. list_for_each_entry(connector, &dev->mode_config.connector_list, base.head)
  1160. intel_backlight_device_unregister(connector);
  1161. }