root/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c

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

DEFINITIONS

This source file includes following definitions.
  1. gf119_sor_dp_watermark
  2. gf119_sor_dp_audio_sym
  3. gf119_sor_dp_audio
  4. gf119_sor_dp_vcpi
  5. gf119_sor_dp_drive
  6. gf119_sor_dp_pattern
  7. gf119_sor_dp_links
  8. gf119_sor_clock
  9. gf119_sor_state
  10. gf119_sor_new
  11. gf119_sor_cnt

   1 /*
   2  * Copyright 2012 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 "ior.h"
  25 
  26 #include <subdev/timer.h>
  27 
  28 void
  29 gf119_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
  30 {
  31         struct nvkm_device *device = sor->disp->engine.subdev.device;
  32         const u32 hoff = head * 0x800;
  33         nvkm_mask(device, 0x616610 + hoff, 0x0800003f, 0x08000000 | watermark);
  34 }
  35 
  36 void
  37 gf119_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
  38 {
  39         struct nvkm_device *device = sor->disp->engine.subdev.device;
  40         const u32 hoff = head * 0x800;
  41         nvkm_mask(device, 0x616620 + hoff, 0x0000ffff, h);
  42         nvkm_mask(device, 0x616624 + hoff, 0x00ffffff, v);
  43 }
  44 
  45 void
  46 gf119_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
  47 {
  48         struct nvkm_device *device = sor->disp->engine.subdev.device;
  49         const u32 hoff = 0x800 * head;
  50         const u32 data = 0x80000000 | (0x00000001 * enable);
  51         const u32 mask = 0x8000000d;
  52         nvkm_mask(device, 0x616618 + hoff, mask, data);
  53         nvkm_msec(device, 2000,
  54                 if (!(nvkm_rd32(device, 0x616618 + hoff) & 0x80000000))
  55                         break;
  56         );
  57 }
  58 
  59 void
  60 gf119_sor_dp_vcpi(struct nvkm_ior *sor, int head,
  61                   u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
  62 {
  63         struct nvkm_device *device = sor->disp->engine.subdev.device;
  64         const u32 hoff = head * 0x800;
  65 
  66         nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
  67         nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
  68 }
  69 
  70 void
  71 gf119_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
  72 {
  73         struct nvkm_device *device = sor->disp->engine.subdev.device;
  74         const u32  loff = nv50_sor_link(sor);
  75         const u32 shift = sor->func->dp.lanes[ln] * 8;
  76         u32 data[4];
  77 
  78         data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
  79         data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
  80         data[2] = nvkm_rd32(device, 0x61c130 + loff);
  81         if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
  82                 data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
  83         nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
  84         nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
  85         nvkm_wr32(device, 0x61c130 + loff, data[2]);
  86         data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
  87         nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
  88 }
  89 
  90 void
  91 gf119_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
  92 {
  93         struct nvkm_device *device = sor->disp->engine.subdev.device;
  94         const u32 soff = nv50_ior_base(sor);
  95         nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
  96 }
  97 
  98 int
  99 gf119_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
 100 {
 101         struct nvkm_device *device = sor->disp->engine.subdev.device;
 102         const u32 soff = nv50_ior_base(sor);
 103         const u32 loff = nv50_sor_link(sor);
 104         u32 dpctrl = 0x00000000;
 105         u32 clksor = 0x00000000;
 106 
 107         clksor |= sor->dp.bw << 18;
 108         dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
 109         if (sor->dp.mst)
 110                 dpctrl |= 0x40000000;
 111         if (sor->dp.ef)
 112                 dpctrl |= 0x00004000;
 113 
 114         nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
 115         nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
 116         return 0;
 117 }
 118 
 119 void
 120 gf119_sor_clock(struct nvkm_ior *sor)
 121 {
 122         struct nvkm_device *device = sor->disp->engine.subdev.device;
 123         const u32 soff = nv50_ior_base(sor);
 124         u32 div1 = sor->asy.link == 3;
 125         u32 div2 = sor->asy.link == 3;
 126         if (sor->asy.proto == TMDS) {
 127                 const u32 speed = sor->tmds.high_speed ? 0x14 : 0x0a;
 128                 nvkm_mask(device, 0x612300 + soff, 0x007c0000, speed << 18);
 129                 if (sor->tmds.high_speed)
 130                         div2 = 1;
 131         }
 132         nvkm_mask(device, 0x612300 + soff, 0x00000707, (div2 << 8) | div1);
 133 }
 134 
 135 void
 136 gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
 137 {
 138         struct nvkm_device *device = sor->disp->engine.subdev.device;
 139         const u32 coff = (state == &sor->asy) * 0x20000 + sor->id * 0x20;
 140         u32 ctrl = nvkm_rd32(device, 0x640200 + coff);
 141 
 142         state->proto_evo = (ctrl & 0x00000f00) >> 8;
 143         switch (state->proto_evo) {
 144         case 0: state->proto = LVDS; state->link = 1; break;
 145         case 1: state->proto = TMDS; state->link = 1; break;
 146         case 2: state->proto = TMDS; state->link = 2; break;
 147         case 5: state->proto = TMDS; state->link = 3; break;
 148         case 8: state->proto =   DP; state->link = 1; break;
 149         case 9: state->proto =   DP; state->link = 2; break;
 150         default:
 151                 state->proto = UNKNOWN;
 152                 break;
 153         }
 154 
 155         state->head = ctrl & 0x0000000f;
 156 }
 157 
 158 static const struct nvkm_ior_func
 159 gf119_sor = {
 160         .state = gf119_sor_state,
 161         .power = nv50_sor_power,
 162         .clock = gf119_sor_clock,
 163         .hdmi = {
 164                 .ctrl = gf119_hdmi_ctrl,
 165         },
 166         .dp = {
 167                 .lanes = { 2, 1, 0, 3 },
 168                 .links = gf119_sor_dp_links,
 169                 .power = g94_sor_dp_power,
 170                 .pattern = gf119_sor_dp_pattern,
 171                 .drive = gf119_sor_dp_drive,
 172                 .vcpi = gf119_sor_dp_vcpi,
 173                 .audio = gf119_sor_dp_audio,
 174                 .audio_sym = gf119_sor_dp_audio_sym,
 175                 .watermark = gf119_sor_dp_watermark,
 176         },
 177         .hda = {
 178                 .hpd = gf119_hda_hpd,
 179                 .eld = gf119_hda_eld,
 180         },
 181 };
 182 
 183 int
 184 gf119_sor_new(struct nvkm_disp *disp, int id)
 185 {
 186         return nvkm_ior_new_(&gf119_sor, disp, SOR, id);
 187 }
 188 
 189 int
 190 gf119_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
 191 {
 192         struct nvkm_device *device = disp->engine.subdev.device;
 193         *pmask = (nvkm_rd32(device, 0x612004) & 0x0000ff00) >> 8;
 194         return 8;
 195 }

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