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 25#include "nvc0.h" 26 27/******************************************************************************* 28 * Perfmon object classes 29 ******************************************************************************/ 30 31/******************************************************************************* 32 * PPM context 33 ******************************************************************************/ 34 35/******************************************************************************* 36 * PPM engine/subdev functions 37 ******************************************************************************/ 38 39static const struct nouveau_specdom 40nve0_perfmon_hub[] = { 41 { 0x60, (const struct nouveau_specsig[]) { 42 { 0x47, "hub00_user_0" }, 43 {} 44 }, &nvc0_perfctr_func }, 45 { 0x40, (const struct nouveau_specsig[]) { 46 { 0x27, "hub01_user_0" }, 47 {} 48 }, &nvc0_perfctr_func }, 49 { 0x60, (const struct nouveau_specsig[]) { 50 { 0x47, "hub02_user_0" }, 51 {} 52 }, &nvc0_perfctr_func }, 53 { 0x60, (const struct nouveau_specsig[]) { 54 { 0x47, "hub03_user_0" }, 55 {} 56 }, &nvc0_perfctr_func }, 57 { 0x40, (const struct nouveau_specsig[]) { 58 { 0x03, "host_mmio_rd" }, 59 { 0x27, "hub04_user_0" }, 60 {} 61 }, &nvc0_perfctr_func }, 62 { 0x60, (const struct nouveau_specsig[]) { 63 { 0x47, "hub05_user_0" }, 64 {} 65 }, &nvc0_perfctr_func }, 66 { 0xc0, (const struct nouveau_specsig[]) { 67 { 0x74, "host_fb_rd3x" }, 68 { 0x75, "host_fb_rd3x_2" }, 69 { 0xa7, "hub06_user_0" }, 70 {} 71 }, &nvc0_perfctr_func }, 72 { 0x60, (const struct nouveau_specsig[]) { 73 { 0x47, "hub07_user_0" }, 74 {} 75 }, &nvc0_perfctr_func }, 76 {} 77}; 78 79static const struct nouveau_specdom 80nve0_perfmon_gpc[] = { 81 { 0xe0, (const struct nouveau_specsig[]) { 82 { 0xc7, "gpc00_user_0" }, 83 {} 84 }, &nvc0_perfctr_func }, 85 {} 86}; 87 88static const struct nouveau_specdom 89nve0_perfmon_part[] = { 90 { 0x60, (const struct nouveau_specsig[]) { 91 { 0x47, "part00_user_0" }, 92 {} 93 }, &nvc0_perfctr_func }, 94 { 0x60, (const struct nouveau_specsig[]) { 95 { 0x47, "part01_user_0" }, 96 {} 97 }, &nvc0_perfctr_func }, 98 {} 99}; 100 101static int 102nve0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 103 struct nouveau_oclass *oclass, void *data, u32 size, 104 struct nouveau_object **pobject) 105{ 106 struct nvc0_perfmon_priv *priv; 107 u32 mask; 108 int ret; 109 110 ret = nouveau_perfmon_create(parent, engine, oclass, &priv); 111 *pobject = nv_object(priv); 112 if (ret) 113 return ret; 114 115 /* PDAEMON */ 116 ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, 117 nve0_perfmon_pwr); 118 if (ret) 119 return ret; 120 121 /* HUB */ 122 ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200, 123 nve0_perfmon_hub); 124 if (ret) 125 return ret; 126 127 /* GPC */ 128 mask = (1 << nv_rd32(priv, 0x022430)) - 1; 129 mask &= ~nv_rd32(priv, 0x022504); 130 mask &= ~nv_rd32(priv, 0x022584); 131 132 ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000, 133 0x1000, 0x200, nve0_perfmon_gpc); 134 if (ret) 135 return ret; 136 137 /* PART */ 138 mask = (1 << nv_rd32(priv, 0x022438)) - 1; 139 mask &= ~nv_rd32(priv, 0x022548); 140 mask &= ~nv_rd32(priv, 0x0225c8); 141 142 ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000, 143 0x1000, 0x200, nve0_perfmon_part); 144 if (ret) 145 return ret; 146 147 nv_engine(priv)->cclass = &nouveau_perfmon_cclass; 148 nv_engine(priv)->sclass = nouveau_perfmon_sclass; 149 priv->base.last = 7; 150 return 0; 151} 152 153struct nouveau_oclass 154nve0_perfmon_oclass = { 155 .handle = NV_ENGINE(PERFMON, 0xe0), 156 .ofuncs = &(struct nouveau_ofuncs) { 157 .ctor = nve0_perfmon_ctor, 158 .dtor = _nouveau_perfmon_dtor, 159 .init = _nouveau_perfmon_init, 160 .fini = nvc0_perfmon_fini, 161 }, 162}; 163