Home | History | Annotate | Line # | Download | only in bios
      1 /*	$NetBSD: nouveau_nvkm_subdev_bios_vmap.c,v 1.3 2021/12/18 23:45:38 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2012 Nouveau Community
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: Martin Peres
     25  */
     26 #include <sys/cdefs.h>
     27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_bios_vmap.c,v 1.3 2021/12/18 23:45:38 riastradh Exp $");
     28 
     29 #include <subdev/bios.h>
     30 #include <subdev/bios/bit.h>
     31 #include <subdev/bios/vmap.h>
     32 
     33 u32
     34 nvbios_vmap_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
     35 {
     36 	struct bit_entry bit_P;
     37 	u32 vmap = 0;
     38 
     39 	if (!bit_entry(bios, 'P', &bit_P)) {
     40 		if (bit_P.version == 2) {
     41 			vmap = nvbios_rd32(bios, bit_P.offset + 0x20);
     42 			if (vmap) {
     43 				*ver = nvbios_rd08(bios, vmap + 0);
     44 				switch (*ver) {
     45 				case 0x10:
     46 				case 0x20:
     47 					*hdr = nvbios_rd08(bios, vmap + 1);
     48 					*cnt = nvbios_rd08(bios, vmap + 3);
     49 					*len = nvbios_rd08(bios, vmap + 2);
     50 					return vmap;
     51 				default:
     52 					break;
     53 				}
     54 			}
     55 		}
     56 	}
     57 
     58 	return 0;
     59 }
     60 
     61 u32
     62 nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
     63 		  struct nvbios_vmap *info)
     64 {
     65 	u32 vmap = nvbios_vmap_table(bios, ver, hdr, cnt, len);
     66 	memset(info, 0x00, sizeof(*info));
     67 	switch (!!vmap * *ver) {
     68 	case 0x10:
     69 		info->max0 = 0xff;
     70 		info->max1 = 0xff;
     71 		info->max2 = 0xff;
     72 		break;
     73 	case 0x20:
     74 		info->max0 = nvbios_rd08(bios, vmap + 0x7);
     75 		info->max1 = nvbios_rd08(bios, vmap + 0x8);
     76 		if (*len >= 0xc)
     77 			info->max2 = nvbios_rd08(bios, vmap + 0xc);
     78 		else
     79 			info->max2 = 0xff;
     80 		break;
     81 	}
     82 	return vmap;
     83 }
     84 
     85 u32
     86 nvbios_vmap_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
     87 {
     88 	u8  hdr, cnt;
     89 	u32 vmap = nvbios_vmap_table(bios, ver, &hdr, &cnt, len);
     90 	if (vmap && idx < cnt) {
     91 		vmap = vmap + hdr + (idx * *len);
     92 		return vmap;
     93 	}
     94 	return 0;
     95 }
     96 
     97 u32
     98 nvbios_vmap_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
     99 			struct nvbios_vmap_entry *info)
    100 {
    101 	u32 vmap = nvbios_vmap_entry(bios, idx, ver, len);
    102 	memset(info, 0x00, sizeof(*info));
    103 	switch (!!vmap * *ver) {
    104 	case 0x10:
    105 		info->link   = 0xff;
    106 		info->min    = nvbios_rd32(bios, vmap + 0x00);
    107 		info->max    = nvbios_rd32(bios, vmap + 0x04);
    108 		info->arg[0] = nvbios_rd32(bios, vmap + 0x08);
    109 		info->arg[1] = nvbios_rd32(bios, vmap + 0x0c);
    110 		info->arg[2] = nvbios_rd32(bios, vmap + 0x10);
    111 		break;
    112 	case 0x20:
    113 		info->mode   = nvbios_rd08(bios, vmap + 0x00);
    114 		info->link   = nvbios_rd08(bios, vmap + 0x01);
    115 		info->min    = nvbios_rd32(bios, vmap + 0x02);
    116 		info->max    = nvbios_rd32(bios, vmap + 0x06);
    117 		info->arg[0] = nvbios_rd32(bios, vmap + 0x0a);
    118 		info->arg[1] = nvbios_rd32(bios, vmap + 0x0e);
    119 		info->arg[2] = nvbios_rd32(bios, vmap + 0x12);
    120 		info->arg[3] = nvbios_rd32(bios, vmap + 0x16);
    121 		info->arg[4] = nvbios_rd32(bios, vmap + 0x1a);
    122 		info->arg[5] = nvbios_rd32(bios, vmap + 0x1e);
    123 		break;
    124 	}
    125 	return vmap;
    126 }
    127