vga_isa.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer as
  12. * the first lines of this file unmodified.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include <sys/cdefs.h>
  29. #include "opt_vga.h"
  30. #include "opt_fb.h"
  31. #include "opt_syscons.h" /* should be removed in the future, XXX */
  32. #include <sys/param.h>
  33. #include <sys/systm.h>
  34. #include <sys/kernel.h>
  35. #include <sys/malloc.h>
  36. #include <sys/module.h>
  37. #include <sys/conf.h>
  38. #include <sys/bus.h>
  39. #include <sys/fbio.h>
  40. #include <machine/bus.h>
  41. #include <machine/resource.h>
  42. #include <sys/rman.h>
  43. #include <vm/vm.h>
  44. #include <vm/pmap.h>
  45. #include <machine/md_var.h>
  46. #ifdef __i386__
  47. #include <machine/pc/bios.h>
  48. #endif
  49. #include <dev/fb/fbreg.h>
  50. #include <dev/fb/vgareg.h>
  51. #include <isa/isareg.h>
  52. #include <isa/isavar.h>
  53. #define VGA_ID 0x0009d041 /* PNP0900 */
  54. static struct isa_pnp_id vga_ids[] = {
  55. { VGA_ID, NULL }, /* PNP0900 */
  56. { 0, NULL },
  57. };
  58. static void
  59. vga_suspend(device_t dev)
  60. {
  61. vga_softc_t *sc;
  62. int nbytes;
  63. sc = device_get_softc(dev);
  64. /* Save the video state across the suspend. */
  65. if (sc->state_buf != NULL)
  66. goto save_palette;
  67. nbytes = vidd_save_state(sc->adp, NULL, 0);
  68. if (nbytes <= 0)
  69. goto save_palette;
  70. sc->state_buf = malloc(nbytes, M_TEMP, M_NOWAIT);
  71. if (sc->state_buf == NULL)
  72. goto save_palette;
  73. if (bootverbose)
  74. device_printf(dev, "saving %d bytes of video state\n", nbytes);
  75. if (vidd_save_state(sc->adp, sc->state_buf, nbytes) != 0) {
  76. device_printf(dev, "failed to save state (nbytes=%d)\n",
  77. nbytes);
  78. free(sc->state_buf, M_TEMP);
  79. sc->state_buf = NULL;
  80. }
  81. save_palette:
  82. /* Save the color palette across the suspend. */
  83. if (sc->pal_buf != NULL)
  84. return;
  85. sc->pal_buf = malloc(256 * 3, M_TEMP, M_NOWAIT);
  86. if (sc->pal_buf == NULL)
  87. return;
  88. if (bootverbose)
  89. device_printf(dev, "saving color palette\n");
  90. if (vidd_save_palette(sc->adp, sc->pal_buf) != 0) {
  91. device_printf(dev, "failed to save palette\n");
  92. free(sc->pal_buf, M_TEMP);
  93. sc->pal_buf = NULL;
  94. }
  95. }
  96. static void
  97. vga_resume(device_t dev)
  98. {
  99. vga_softc_t *sc;
  100. sc = device_get_softc(dev);
  101. if (sc->state_buf != NULL) {
  102. if (vidd_load_state(sc->adp, sc->state_buf) != 0)
  103. device_printf(dev, "failed to reload state\n");
  104. free(sc->state_buf, M_TEMP);
  105. sc->state_buf = NULL;
  106. }
  107. if (sc->pal_buf != NULL) {
  108. if (vidd_load_palette(sc->adp, sc->pal_buf) != 0)
  109. device_printf(dev, "failed to reload palette\n");
  110. free(sc->pal_buf, M_TEMP);
  111. sc->pal_buf = NULL;
  112. }
  113. }
  114. static void
  115. isavga_identify(driver_t *driver, device_t parent)
  116. {
  117. BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, VGA_DRIVER_NAME, 0);
  118. }
  119. static int
  120. isavga_probe(device_t dev)
  121. {
  122. video_adapter_t adp;
  123. int error;
  124. /* No pnp support */
  125. if (isa_get_vendorid(dev))
  126. return (ENXIO);
  127. error = vga_probe_unit(device_get_unit(dev), &adp, device_get_flags(dev));
  128. if (error == 0) {
  129. device_set_desc(dev, "Generic ISA VGA");
  130. bus_set_resource(dev, SYS_RES_IOPORT, 0,
  131. adp.va_io_base, adp.va_io_size);
  132. bus_set_resource(dev, SYS_RES_MEMORY, 0,
  133. adp.va_mem_base, adp.va_mem_size);
  134. isa_set_vendorid(dev, VGA_ID);
  135. isa_set_logicalid(dev, VGA_ID);
  136. #if 0
  137. isa_set_port(dev, adp.va_io_base);
  138. isa_set_portsize(dev, adp.va_io_size);
  139. isa_set_maddr(dev, adp.va_mem_base);
  140. isa_set_msize(dev, adp.va_mem_size);
  141. #endif
  142. }
  143. return (error);
  144. }
  145. static int
  146. isavga_attach(device_t dev)
  147. {
  148. vga_softc_t *sc;
  149. int unit;
  150. int rid;
  151. int error;
  152. unit = device_get_unit(dev);
  153. sc = device_get_softc(dev);
  154. rid = 0;
  155. bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
  156. RF_ACTIVE | RF_SHAREABLE);
  157. rid = 0;
  158. bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  159. RF_ACTIVE | RF_SHAREABLE);
  160. error = vga_attach_unit(unit, sc, device_get_flags(dev));
  161. if (error)
  162. return (error);
  163. if (0 && bootverbose)
  164. vidd_diag(sc->adp, bootverbose);
  165. #if 0 /* experimental */
  166. device_add_child(dev, "fb", DEVICE_UNIT_ANY);
  167. bus_generic_attach(dev);
  168. #endif
  169. return (0);
  170. }
  171. static int
  172. isavga_suspend(device_t dev)
  173. {
  174. int error;
  175. error = bus_generic_suspend(dev);
  176. if (error != 0)
  177. return (error);
  178. vga_suspend(dev);
  179. return (error);
  180. }
  181. static int
  182. isavga_resume(device_t dev)
  183. {
  184. vga_resume(dev);
  185. return (bus_generic_resume(dev));
  186. }
  187. static device_method_t isavga_methods[] = {
  188. DEVMETHOD(device_identify, isavga_identify),
  189. DEVMETHOD(device_probe, isavga_probe),
  190. DEVMETHOD(device_attach, isavga_attach),
  191. DEVMETHOD(device_suspend, isavga_suspend),
  192. DEVMETHOD(device_resume, isavga_resume),
  193. DEVMETHOD_END
  194. };
  195. static driver_t isavga_driver = {
  196. VGA_DRIVER_NAME,
  197. isavga_methods,
  198. sizeof(vga_softc_t),
  199. };
  200. DRIVER_MODULE(vga, isa, isavga_driver, 0, 0);
  201. static void
  202. vgapm_identify(driver_t *driver, device_t parent)
  203. {
  204. if (device_get_flags(parent) != 0)
  205. device_add_child(parent, "vgapm", 0);
  206. }
  207. static int
  208. vgapm_probe(device_t dev)
  209. {
  210. device_set_desc(dev, "VGA suspend/resume");
  211. device_quiet(dev);
  212. return (BUS_PROBE_DEFAULT);
  213. }
  214. static int
  215. vgapm_attach(device_t dev)
  216. {
  217. bus_generic_probe(dev);
  218. bus_generic_attach(dev);
  219. return (0);
  220. }
  221. static int
  222. vgapm_suspend(device_t dev)
  223. {
  224. device_t vga_dev;
  225. int error;
  226. error = bus_generic_suspend(dev);
  227. if (error != 0)
  228. return (error);
  229. vga_dev = devclass_get_device(devclass_find(VGA_DRIVER_NAME), 0);
  230. if (vga_dev == NULL)
  231. return (0);
  232. vga_suspend(vga_dev);
  233. return (0);
  234. }
  235. static int
  236. vgapm_resume(device_t dev)
  237. {
  238. device_t vga_dev;
  239. vga_dev = devclass_get_device(devclass_find(VGA_DRIVER_NAME), 0);
  240. if (vga_dev != NULL)
  241. vga_resume(vga_dev);
  242. return (bus_generic_resume(dev));
  243. }
  244. static device_method_t vgapm_methods[] = {
  245. DEVMETHOD(device_identify, vgapm_identify),
  246. DEVMETHOD(device_probe, vgapm_probe),
  247. DEVMETHOD(device_attach, vgapm_attach),
  248. DEVMETHOD(device_suspend, vgapm_suspend),
  249. DEVMETHOD(device_resume, vgapm_resume),
  250. { 0, 0 }
  251. };
  252. static driver_t vgapm_driver = {
  253. "vgapm",
  254. vgapm_methods,
  255. 0
  256. };
  257. DRIVER_MODULE(vgapm, vgapci, vgapm_driver, 0, 0);
  258. ISA_PNP_INFO(vga_ids);