root/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nv50_devinit_pll_set
  2. nv50_devinit_disable
  3. nv50_devinit_preinit
  4. nv50_devinit_init
  5. nv50_devinit_new_
  6. nv50_devinit_new

   1 /*
   2  * Copyright 2013 Red Hat Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: Ben Skeggs
  23  */
  24 #include "nv50.h"
  25 
  26 #include <subdev/bios.h>
  27 #include <subdev/bios/dcb.h>
  28 #include <subdev/bios/disp.h>
  29 #include <subdev/bios/init.h>
  30 #include <subdev/bios/pll.h>
  31 #include <subdev/clk/pll.h>
  32 #include <subdev/vga.h>
  33 
  34 int
  35 nv50_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
  36 {
  37         struct nvkm_subdev *subdev = &init->subdev;
  38         struct nvkm_device *device = subdev->device;
  39         struct nvkm_bios *bios = device->bios;
  40         struct nvbios_pll info;
  41         int N1, M1, N2, M2, P;
  42         int ret;
  43 
  44         ret = nvbios_pll_parse(bios, type, &info);
  45         if (ret) {
  46                 nvkm_error(subdev, "failed to retrieve pll data, %d\n", ret);
  47                 return ret;
  48         }
  49 
  50         ret = nv04_pll_calc(subdev, &info, freq, &N1, &M1, &N2, &M2, &P);
  51         if (!ret) {
  52                 nvkm_error(subdev, "failed pll calculation\n");
  53                 return -EINVAL;
  54         }
  55 
  56         switch (info.type) {
  57         case PLL_VPLL0:
  58         case PLL_VPLL1:
  59                 nvkm_wr32(device, info.reg + 0, 0x10000611);
  60                 nvkm_mask(device, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
  61                 nvkm_mask(device, info.reg + 8, 0x7fff00ff, (P  << 28) |
  62                                                             (M2 << 16) | N2);
  63                 break;
  64         case PLL_MEMORY:
  65                 nvkm_mask(device, info.reg + 0, 0x01ff0000,
  66                                                 (P << 22) |
  67                                                 (info.bias_p << 19) |
  68                                                 (P << 16));
  69                 nvkm_wr32(device, info.reg + 4, (N1 << 8) | M1);
  70                 break;
  71         default:
  72                 nvkm_mask(device, info.reg + 0, 0x00070000, (P << 16));
  73                 nvkm_wr32(device, info.reg + 4, (N1 << 8) | M1);
  74                 break;
  75         }
  76 
  77         return 0;
  78 }
  79 
  80 static u64
  81 nv50_devinit_disable(struct nvkm_devinit *init)
  82 {
  83         struct nvkm_device *device = init->subdev.device;
  84         u32 r001540 = nvkm_rd32(device, 0x001540);
  85         u64 disable = 0ULL;
  86 
  87         if (!(r001540 & 0x40000000))
  88                 disable |= (1ULL << NVKM_ENGINE_MPEG);
  89 
  90         return disable;
  91 }
  92 
  93 void
  94 nv50_devinit_preinit(struct nvkm_devinit *base)
  95 {
  96         struct nvkm_subdev *subdev = &base->subdev;
  97         struct nvkm_device *device = subdev->device;
  98 
  99         /* our heuristics can't detect whether the board has had its
 100          * devinit scripts executed or not if the display engine is
 101          * missing, assume it's a secondary gpu which requires post
 102          */
 103         if (!base->post) {
 104                 u64 disable = nvkm_devinit_disable(base);
 105                 if (disable & (1ULL << NVKM_ENGINE_DISP))
 106                         base->post = true;
 107         }
 108 
 109         /* magic to detect whether or not x86 vbios code has executed
 110          * the devinit scripts to initialise the board
 111          */
 112         if (!base->post) {
 113                 if (!nvkm_rdvgac(device, 0, 0x00) &&
 114                     !nvkm_rdvgac(device, 0, 0x1a)) {
 115                         nvkm_debug(subdev, "adaptor not initialised\n");
 116                         base->post = true;
 117                 }
 118         }
 119 }
 120 
 121 void
 122 nv50_devinit_init(struct nvkm_devinit *base)
 123 {
 124         struct nv50_devinit *init = nv50_devinit(base);
 125         struct nvkm_subdev *subdev = &init->base.subdev;
 126         struct nvkm_device *device = subdev->device;
 127         struct nvkm_bios *bios = device->bios;
 128         struct nvbios_outp info;
 129         struct dcb_output outp;
 130         u8  ver = 0xff, hdr, cnt, len;
 131         int i = 0;
 132 
 133         /* if we ran the init tables, we have to execute the first script
 134          * pointer of each dcb entry's display encoder table in order
 135          * to properly initialise each encoder.
 136          */
 137         while (init->base.post && dcb_outp_parse(bios, i, &ver, &hdr, &outp)) {
 138                 if (nvbios_outp_match(bios, outp.hasht, outp.hashm,
 139                                       &ver, &hdr, &cnt, &len, &info)) {
 140                         nvbios_init(subdev, info.script[0],
 141                                 init.outp = &outp;
 142                                 init.or   = ffs(outp.or) - 1;
 143                                 init.link = outp.sorconf.link == 2;
 144                         );
 145                 }
 146                 i++;
 147         }
 148 }
 149 
 150 int
 151 nv50_devinit_new_(const struct nvkm_devinit_func *func,
 152                   struct nvkm_device *device, int index,
 153                   struct nvkm_devinit **pinit)
 154 {
 155         struct nv50_devinit *init;
 156 
 157         if (!(init = kzalloc(sizeof(*init), GFP_KERNEL)))
 158                 return -ENOMEM;
 159         *pinit = &init->base;
 160 
 161         nvkm_devinit_ctor(func, device, index, &init->base);
 162         return 0;
 163 }
 164 
 165 static const struct nvkm_devinit_func
 166 nv50_devinit = {
 167         .preinit = nv50_devinit_preinit,
 168         .init = nv50_devinit_init,
 169         .post = nv04_devinit_post,
 170         .pll_set = nv50_devinit_pll_set,
 171         .disable = nv50_devinit_disable,
 172 };
 173 
 174 int
 175 nv50_devinit_new(struct nvkm_device *device, int index,
 176                  struct nvkm_devinit **pinit)
 177 {
 178         return nv50_devinit_new_(&nv50_devinit, device, index, pinit);
 179 }

/* [<][>][^][v][top][bottom][index][help] */