fsp_graphics.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
  4. */
  5. #define LOG_CATEGORY UCLASS_VIDEO
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <init.h>
  9. #include <log.h>
  10. #include <vbe.h>
  11. #include <video.h>
  12. #include <acpi/acpi_table.h>
  13. #include <asm/fsp/fsp_support.h>
  14. #include <asm/intel_opregion.h>
  15. #include <asm/mtrr.h>
  16. #include <dm/acpi.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. struct pixel {
  19. u8 pos;
  20. u8 size;
  21. };
  22. static const struct fsp_framebuffer {
  23. struct pixel red;
  24. struct pixel green;
  25. struct pixel blue;
  26. struct pixel rsvd;
  27. } fsp_framebuffer_format_map[] = {
  28. [pixel_rgbx_8bpc] = { {0, 8}, {8, 8}, {16, 8}, {24, 8} },
  29. [pixel_bgrx_8bpc] = { {16, 8}, {8, 8}, {0, 8}, {24, 8} },
  30. };
  31. static int save_vesa_mode(struct vesa_mode_info *vesa)
  32. {
  33. const struct hob_graphics_info *ginfo;
  34. const struct fsp_framebuffer *fbinfo;
  35. ginfo = fsp_get_graphics_info(gd->arch.hob_list, NULL);
  36. /*
  37. * If there is no graphics info structure, bail out and keep
  38. * running on the serial console.
  39. *
  40. * Note: on some platforms (eg: Braswell), the FSP will not produce
  41. * the graphics info HOB unless you plug some cables to the display
  42. * interface (eg: HDMI) on the board.
  43. */
  44. if (!ginfo) {
  45. debug("FSP graphics hand-off block not found\n");
  46. return -ENXIO;
  47. }
  48. vesa->x_resolution = ginfo->width;
  49. vesa->y_resolution = ginfo->height;
  50. vesa->bits_per_pixel = 32;
  51. vesa->bytes_per_scanline = ginfo->pixels_per_scanline * 4;
  52. vesa->phys_base_ptr = ginfo->fb_base;
  53. if (ginfo->pixel_format >= pixel_bitmask) {
  54. debug("FSP set unknown framebuffer format: %d\n",
  55. ginfo->pixel_format);
  56. return -EINVAL;
  57. }
  58. fbinfo = &fsp_framebuffer_format_map[ginfo->pixel_format];
  59. vesa->red_mask_size = fbinfo->red.size;
  60. vesa->red_mask_pos = fbinfo->red.pos;
  61. vesa->green_mask_size = fbinfo->green.size;
  62. vesa->green_mask_pos = fbinfo->green.pos;
  63. vesa->blue_mask_size = fbinfo->blue.size;
  64. vesa->blue_mask_pos = fbinfo->blue.pos;
  65. vesa->reserved_mask_size = fbinfo->rsvd.size;
  66. vesa->reserved_mask_pos = fbinfo->rsvd.pos;
  67. return 0;
  68. }
  69. static int fsp_video_probe(struct udevice *dev)
  70. {
  71. struct video_uc_plat *plat = dev_get_uclass_plat(dev);
  72. struct video_priv *uc_priv = dev_get_uclass_priv(dev);
  73. struct vesa_mode_info *vesa = &mode_info.vesa;
  74. int ret;
  75. if (!ll_boot_init())
  76. return 0;
  77. printf("Video: ");
  78. /* Initialize vesa_mode_info structure */
  79. ret = save_vesa_mode(vesa);
  80. if (ret)
  81. goto err;
  82. /*
  83. * The framebuffer base address in the FSP graphics info HOB reflects
  84. * the value assigned by the FSP. After PCI enumeration the framebuffer
  85. * base address may be relocated. Let's get the updated one from device.
  86. *
  87. * For IGD, it seems to be always on BAR2.
  88. */
  89. vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
  90. gd->fb_base = vesa->phys_base_ptr;
  91. ret = vbe_setup_video_priv(vesa, uc_priv, plat);
  92. if (ret)
  93. goto err;
  94. mtrr_add_request(MTRR_TYPE_WRCOMB, vesa->phys_base_ptr, 256 << 20);
  95. mtrr_commit(true);
  96. printf("%dx%dx%d @ %x\n", uc_priv->xsize, uc_priv->ysize,
  97. vesa->bits_per_pixel, vesa->phys_base_ptr);
  98. return 0;
  99. err:
  100. printf("No video mode configured in FSP!\n");
  101. return ret;
  102. }
  103. static int fsp_video_bind(struct udevice *dev)
  104. {
  105. struct video_uc_plat *plat = dev_get_uclass_plat(dev);
  106. /* Set the maximum supported resolution */
  107. plat->size = 2560 * 1600 * 4;
  108. return 0;
  109. }
  110. #ifdef CONFIG_INTEL_GMA_ACPI
  111. static int fsp_video_acpi_write_tables(const struct udevice *dev,
  112. struct acpi_ctx *ctx)
  113. {
  114. struct igd_opregion *opregion;
  115. int ret;
  116. log_debug("ACPI: * IGD OpRegion\n");
  117. opregion = (struct igd_opregion *)ctx->current;
  118. ret = intel_gma_init_igd_opregion((struct udevice *)dev, opregion);
  119. if (ret)
  120. return ret;
  121. acpi_inc_align(ctx, sizeof(struct igd_opregion));
  122. return 0;
  123. }
  124. #endif
  125. struct acpi_ops fsp_video_acpi_ops = {
  126. #ifdef CONFIG_INTEL_GMA_ACPI
  127. .write_tables = fsp_video_acpi_write_tables,
  128. #endif
  129. };
  130. static const struct udevice_id fsp_video_ids[] = {
  131. { .compatible = "fsp-fb" },
  132. { }
  133. };
  134. U_BOOT_DRIVER(fsp_video) = {
  135. .name = "fsp_video",
  136. .id = UCLASS_VIDEO,
  137. .of_match = fsp_video_ids,
  138. .bind = fsp_video_bind,
  139. .probe = fsp_video_probe,
  140. .flags = DM_FLAG_PRE_RELOC,
  141. ACPI_OPS_PTR(&fsp_video_acpi_ops)
  142. };
  143. static struct pci_device_id fsp_video_supported[] = {
  144. { PCI_DEVICE_CLASS(PCI_CLASS_DISPLAY_VGA << 8, 0xffff00) },
  145. { },
  146. };
  147. U_BOOT_PCI_DEVICE(fsp_video, fsp_video_supported);