0003-mainboard-lenovo-t400-Add-initial-hybrid-graphics-su.patch 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. From bbf3462e7442c2cae568e147d3f0eb1195f86991 Mon Sep 17 00:00:00 2001
  2. From: Timothy Pearson <tpearson@raptorengineeringinc.com>
  3. Date: Sun, 5 Apr 2015 18:10:09 -0500
  4. Subject: [PATCH 03/17] mainboard/lenovo/t400: Add initial hybrid graphics
  5. support
  6. TEST: Booted T400 with Intel/ATI hybrid graphics in integrated
  7. mode with native Intel graphics init and verified integrated
  8. panel framebuffer functionality in SeaBIOS and Linux.
  9. Change-Id: I37e72c5dad0d7ab3915cc3d439ae9a4a9b3787e3
  10. Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
  11. ---
  12. src/mainboard/lenovo/t400/cmos.default | 1 +
  13. src/mainboard/lenovo/t400/cmos.layout | 8 +-
  14. src/mainboard/lenovo/t400/romstage.c | 143 +++++++++++++++++++++++++++++++++
  15. 3 files changed, 151 insertions(+), 1 deletion(-)
  16. diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default
  17. index 67b8920..06eec57 100644
  18. --- a/src/mainboard/lenovo/t400/cmos.default
  19. +++ b/src/mainboard/lenovo/t400/cmos.default
  20. @@ -14,3 +14,4 @@ sticky_fn=Disable
  21. power_management_beeps=Enable
  22. low_battery_beep=Enable
  23. sata_mode=AHCI
  24. +hybrid_graphics_mode=Integrated Only
  25. \ No newline at end of file
  26. diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout
  27. index 2dc91bf..44f5d04 100644
  28. --- a/src/mainboard/lenovo/t400/cmos.layout
  29. +++ b/src/mainboard/lenovo/t400/cmos.layout
  30. @@ -85,7 +85,10 @@ entries
  31. # coreboot config options: northbridge
  32. 941 3 e 11 gfx_uma_size
  33. -#944 2 r 0 unused
  34. +# coreboot config options: graphics
  35. +944 2 e 12 hybrid_graphics_mode
  36. +
  37. +#946 2 r 0 unused
  38. # coreboot config options: check sums
  39. 984 16 h 0 check_sum
  40. @@ -137,6 +140,9 @@ enumerations
  41. 11 3 128M
  42. 11 5 96M
  43. 11 6 160M
  44. +12 0 Integrated Only
  45. +12 1 Discrete Only
  46. +12 2 Switchable
  47. # -----------------------------------------------------------------
  48. checksums
  49. diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c
  50. index a739d18..c62df60 100644
  51. --- a/src/mainboard/lenovo/t400/romstage.c
  52. +++ b/src/mainboard/lenovo/t400/romstage.c
  53. @@ -1,6 +1,7 @@
  54. /*
  55. * This file is part of the coreboot project.
  56. *
  57. + * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
  58. * Copyright (C) 2012 secunet Security Networks AG
  59. *
  60. * This program is free software; you can redistribute it and/or
  61. @@ -37,6 +38,118 @@
  62. #define LPC_DEV PCI_DEV(0, 0x1f, 0)
  63. #define MCH_DEV PCI_DEV(0, 0, 0)
  64. +#define HYBRID_GRAPHICS_INTEGRATED_ONLY 0
  65. +#define HYBRID_GRAPHICS_DISCRETE_ONLY 1
  66. +#define HYBRID_GRAPHICS_SWITCHABLE 2
  67. +
  68. +#define HYBRID_GRAPHICS_GP_LVL_BITS 0x004a0000
  69. +#define HYBRID_GRAPHICS_GP_LVL2_BITS 0x00020000
  70. +
  71. +#define HYBRID_GRAPHICS_DETECT_GP_BITS 0x00000010
  72. +
  73. +#define HYBRID_GRAPHICS_INT_CLAIM_VGA 0x2
  74. +#define HYBRID_GRAPHICS_SEC_VGA_EN 0x2
  75. +
  76. +static void hybrid_graphics_configure_switchable_graphics(bool enable)
  77. +{
  78. + uint32_t tmp;
  79. +
  80. + if (enable) {
  81. + /* Disable integrated graphics legacy VGA cycles */
  82. + tmp = pci_read_config16(MCH_DEV, D0F0_GGC);
  83. + pci_write_config16(MCH_DEV, D0F0_GGC, tmp | HYBRID_GRAPHICS_INT_CLAIM_VGA);
  84. +
  85. + /* Enable secondary VGA controller */
  86. + tmp = pci_read_config16(MCH_DEV, D0F0_DEVEN);
  87. + pci_write_config16(MCH_DEV, D0F0_DEVEN, tmp | HYBRID_GRAPHICS_SEC_VGA_EN);
  88. + }
  89. + else {
  90. + /* Enable integrated graphics legacy VGA cycles */
  91. + tmp = pci_read_config16(MCH_DEV, D0F0_GGC);
  92. + pci_write_config16(MCH_DEV, D0F0_GGC, tmp & ~HYBRID_GRAPHICS_INT_CLAIM_VGA);
  93. +
  94. + /* Disable secondary VGA controller */
  95. + tmp = pci_read_config16(MCH_DEV, D0F0_DEVEN);
  96. + pci_write_config16(MCH_DEV, D0F0_DEVEN, tmp & ~HYBRID_GRAPHICS_SEC_VGA_EN);
  97. + }
  98. +}
  99. +
  100. +static void hybrid_graphics_set_up_gpio(void)
  101. +{
  102. + uint32_t tmp;
  103. +
  104. + /* Enable hybrid graphics GPIO lines */
  105. + tmp = inl(DEFAULT_GPIOBASE + GP_IO_USE_SEL);
  106. + tmp = tmp | HYBRID_GRAPHICS_GP_LVL_BITS;
  107. + outl(tmp, DEFAULT_GPIOBASE + GP_IO_USE_SEL);
  108. +
  109. + tmp = inl(DEFAULT_GPIOBASE + GP_IO_USE_SEL2);
  110. + tmp = tmp | HYBRID_GRAPHICS_GP_LVL2_BITS;
  111. + outl(tmp, DEFAULT_GPIOBASE + GP_IO_USE_SEL2);
  112. +
  113. + /* Set hybrid graphics control GPIO lines to output */
  114. + tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL);
  115. + tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL_BITS;
  116. + outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL);
  117. +
  118. + tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL2);
  119. + tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL2_BITS;
  120. + outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL2);
  121. +
  122. + /* Set hybrid graphics detect GPIO lines to input */
  123. + tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL);
  124. + tmp = tmp | HYBRID_GRAPHICS_DETECT_GP_BITS;
  125. + outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL);
  126. +}
  127. +
  128. +static bool hybrid_graphics_installed(void)
  129. +{
  130. + if (inl(DEFAULT_GPIOBASE + GP_LVL) & HYBRID_GRAPHICS_DETECT_GP_BITS)
  131. + return false;
  132. + else
  133. + return true;
  134. +}
  135. +
  136. +static void hybrid_graphics_switch_to_integrated_graphics(void)
  137. +{
  138. + uint32_t tmp;
  139. +
  140. + /* Disable switchable graphics */
  141. + hybrid_graphics_configure_switchable_graphics(false);
  142. +
  143. + /* Configure muxes */
  144. + tmp = inl(DEFAULT_GPIOBASE + GP_LVL);
  145. + tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL_BITS;
  146. + outl(tmp, DEFAULT_GPIOBASE + GP_LVL);
  147. +
  148. + tmp = inl(DEFAULT_GPIOBASE + GP_LVL2);
  149. + tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL2_BITS;
  150. + outl(tmp, DEFAULT_GPIOBASE + GP_LVL2);
  151. +}
  152. +
  153. +static void hybrid_graphics_switch_to_discrete_graphics(void)
  154. +{
  155. + uint32_t tmp;
  156. +
  157. + /* Disable switchable graphics */
  158. + hybrid_graphics_configure_switchable_graphics(false);
  159. +
  160. + /* Configure muxes */
  161. + tmp = inl(DEFAULT_GPIOBASE + GP_LVL);
  162. + tmp = tmp | HYBRID_GRAPHICS_GP_LVL_BITS;
  163. + outl(tmp, DEFAULT_GPIOBASE + GP_LVL);
  164. +
  165. + tmp = inl(DEFAULT_GPIOBASE + GP_LVL2);
  166. + tmp = tmp | HYBRID_GRAPHICS_GP_LVL2_BITS;
  167. + outl(tmp, DEFAULT_GPIOBASE + GP_LVL2);
  168. +}
  169. +
  170. +static void hybrid_graphics_switch_to_dual_graphics(void)
  171. +{
  172. + /* Enable switchable graphics */
  173. + hybrid_graphics_configure_switchable_graphics(true);
  174. +}
  175. +
  176. static void default_southbridge_gpio_setup(void)
  177. {
  178. outl(0x197e23fe, DEFAULT_GPIOBASE + GP_IO_USE_SEL);
  179. @@ -98,6 +211,31 @@ void main(unsigned long bist)
  180. default_southbridge_gpio_setup();
  181. + uint8_t hybrid_graphics_mode = HYBRID_GRAPHICS_INTEGRATED_ONLY;
  182. + get_option(&hybrid_graphics_mode, "hybrid_graphics_mode");
  183. +
  184. + /* Set up hybrid graphics */
  185. + hybrid_graphics_set_up_gpio();
  186. + if (hybrid_graphics_installed()) {
  187. + /* Select appropriate hybrid graphics device */
  188. + printk(BIOS_DEBUG, "Hybrid graphics available, setting mode %d\n", hybrid_graphics_mode);
  189. + if (hybrid_graphics_mode == HYBRID_GRAPHICS_INTEGRATED_ONLY)
  190. + hybrid_graphics_switch_to_integrated_graphics();
  191. + else if (hybrid_graphics_mode == HYBRID_GRAPHICS_DISCRETE_ONLY)
  192. + hybrid_graphics_switch_to_discrete_graphics();
  193. + else if (hybrid_graphics_mode == HYBRID_GRAPHICS_SWITCHABLE)
  194. + hybrid_graphics_switch_to_integrated_graphics();
  195. + /* Switchable graphics are fully enabled after raminit */
  196. + /* FIXME
  197. + * Enabling switchable graphics prevents bootup!
  198. + * Debug and fix appropriately...
  199. + */
  200. + }
  201. + else {
  202. + printk(BIOS_DEBUG, "Hybrid graphics not installed\n");
  203. + hybrid_graphics_switch_to_integrated_graphics();
  204. + }
  205. +
  206. /* ASPM related setting, set early by original BIOS. */
  207. DMIBAR16(0x204) &= ~(3 << 10);
  208. @@ -177,6 +315,11 @@ void main(unsigned long bist)
  209. outl(inl(DEFAULT_GPIOBASE + 0x38) & ~0x400, DEFAULT_GPIOBASE + 0x38);
  210. cbmem_initted = !cbmem_recovery(s3resume);
  211. +
  212. + if (hybrid_graphics_installed())
  213. + if (hybrid_graphics_mode == HYBRID_GRAPHICS_SWITCHABLE)
  214. + hybrid_graphics_switch_to_dual_graphics();
  215. +
  216. #if CONFIG_HAVE_ACPI_RESUME
  217. /* If there is no high memory area, we didn't boot before, so
  218. * this is not a resume. In that case we just create the cbmem toc.
  219. --
  220. 1.9.1