2 * Copyright (c) 2014-2016 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 * Authors: Andreas Sandberg
40 #include "dev/arm/gpu_nomali.hh"
42 #include "debug/NoMali.hh"
43 #include "dev/arm/base_gic.hh"
44 #include "dev/arm/realview.hh"
45 #include "enums/MemoryMode.hh"
46 #include "mem/packet_access.hh"
47 #include "nomali/lib/mali_midg_regmap.h"
48 #include "params/CustomNoMaliGpu.hh"
49 #include "params/NoMaliGpu.hh"
51 static const std::map
<Enums::NoMaliGpuType
, nomali_gpu_type_t
> gpuTypeMap
{
52 { Enums::T60x
, NOMALI_GPU_T60X
},
53 { Enums::T62x
, NOMALI_GPU_T62X
},
54 { Enums::T760
, NOMALI_GPU_T760
},
57 NoMaliGpu::NoMaliGpu(const NoMaliGpuParams
*p
)
60 platform(p
->platform
),
62 { NOMALI_INT_GPU
, p
->int_gpu
},
63 { NOMALI_INT_JOB
, p
->int_job
},
64 { NOMALI_INT_MMU
, p
->int_mmu
},
67 if (nomali_api_version() != NOMALI_API_VERSION
)
68 panic("NoMali library API mismatch!\n");
70 /* Setup the GPU configuration based on our param struct */
72 memset(&cfg
, 0, sizeof(cfg
));
74 const auto it_gpu(gpuTypeMap
.find(p
->gpu_type
));
75 if (it_gpu
== gpuTypeMap
.end()) {
76 fatal("Unrecognized GPU type: %s (%i)\n",
77 Enums::NoMaliGpuTypeStrings
[p
->gpu_type
], p
->gpu_type
);
79 cfg
.type
= it_gpu
->second
;
81 cfg
.ver_maj
= p
->ver_maj
;
82 cfg
.ver_min
= p
->ver_min
;
83 cfg
.ver_status
= p
->ver_status
;
86 nomali_create(&nomali
, &cfg
),
87 "Failed to instantiate NoMali");
90 /* Setup an interrupt callback */
91 nomali_callback_t cbk_int
;
92 cbk_int
.type
= NOMALI_CALLBACK_INT
;
93 cbk_int
.usr
= (void *)this;
94 cbk_int
.func
.interrupt
= NoMaliGpu::_interrupt
;
97 /* Setup a reset callback */
98 nomali_callback_t cbk_rst
;
99 cbk_rst
.type
= NOMALI_CALLBACK_RESET
;
100 cbk_rst
.usr
= (void *)this;
101 cbk_rst
.func
.reset
= NoMaliGpu::_reset
;
102 setCallback(cbk_rst
);
105 nomali_get_info(nomali
, &nomaliInfo
),
106 "Failed to get NoMali information struct");
109 NoMaliGpu::~NoMaliGpu()
111 nomali_destroy(nomali
);
120 /* Reset the GPU here since the reset callback won't have been
121 * installed when the GPU was reset at instantiation time.
127 NoMaliGpu::serialize(CheckpointOut
&cp
) const
129 std::vector
<uint32_t> regs(nomaliInfo
.reg_size
>> 2);
131 for (int i
= 0; i
< nomaliInfo
.reg_size
; i
+= 4)
132 regs
[i
>> 2] = readRegRaw(i
);
134 SERIALIZE_CONTAINER(regs
);
138 NoMaliGpu::unserialize(CheckpointIn
&cp
)
140 std::vector
<uint32_t> regs(nomaliInfo
.reg_size
>> 2);
142 UNSERIALIZE_CONTAINER(regs
);
144 for (int i
= 0; i
< nomaliInfo
.reg_size
; i
+= 4)
145 writeRegRaw(i
, regs
[i
>> 2]);
149 NoMaliGpu::read(PacketPtr pkt
)
151 assert(pkt
->getAddr() >= pioAddr
);
152 const Addr
addr(pkt
->getAddr() - pioAddr
);
153 const unsigned size(pkt
->getSize());
155 if (addr
+ size
>= nomaliInfo
.reg_size
)
156 panic("GPU register '0x%x' out of range!\n", addr
);
159 panic("Unexpected GPU register read size: %i\n", size
);
161 panic("Unaligned GPU read: %i\n", size
);
163 pkt
->setLE
<uint32_t>(readReg(addr
));
170 NoMaliGpu::write(PacketPtr pkt
)
172 assert(pkt
->getAddr() >= pioAddr
);
173 const Addr
addr(pkt
->getAddr() - pioAddr
);
174 const unsigned size(pkt
->getSize());
176 if (addr
+ size
>= nomaliInfo
.reg_size
)
177 panic("GPU register '0x%x' out of range!\n", addr
);
180 panic("Unexpected GPU register write size: %i\n", size
);
182 panic("Unaligned GPU write: %i\n", size
);
184 writeReg(addr
, pkt
->getLE
<uint32_t>());
185 pkt
->makeAtomicResponse();
191 NoMaliGpu::getAddrRanges() const
193 return AddrRangeList({ RangeSize(pioAddr
, nomaliInfo
.reg_size
) });
199 DPRINTF(NoMali
, "reset()\n");
202 nomali_reset(nomali
),
203 "Failed to reset GPU");
207 NoMaliGpu::readReg(nomali_addr_t reg
)
212 nomali_reg_read(nomali
, &value
, reg
),
213 "GPU register read failed");
215 DPRINTF(NoMali
, "readReg(0x%x): 0x%x\n",
223 NoMaliGpu::writeReg(nomali_addr_t reg
, uint32_t value
)
225 DPRINTF(NoMali
, "writeReg(0x%x, 0x%x)\n",
229 nomali_reg_write(nomali
, reg
, value
),
230 "GPU register write failed");
234 NoMaliGpu::readRegRaw(nomali_addr_t reg
) const
239 nomali_reg_read_raw(nomali
, &value
, reg
),
240 "GPU raw register read failed");
247 NoMaliGpu::writeRegRaw(nomali_addr_t reg
, uint32_t value
)
250 nomali_reg_write_raw(nomali
, reg
, value
),
251 "GPU raw register write failed");
255 NoMaliGpu::intState(nomali_int_t intno
)
259 nomali_int_state(nomali
, &state
, intno
),
260 "Failed to get interrupt state");
266 NoMaliGpu::gpuPanic(nomali_error_t err
, const char *msg
)
268 panic("%s: %s\n", msg
, nomali_errstr(err
));
273 NoMaliGpu::onInterrupt(nomali_int_t intno
, bool set
)
275 const auto it_int(interruptMap
.find(intno
));
276 if (it_int
== interruptMap
.end())
277 panic("Unhandled interrupt from NoMali: %i\n", intno
);
279 DPRINTF(NoMali
, "Interrupt %i->%i: %i\n",
280 intno
, it_int
->second
, set
);
283 assert(platform
->gic
);
286 platform
->gic
->sendInt(it_int
->second
);
288 platform
->gic
->clearInt(it_int
->second
);
294 DPRINTF(NoMali
, "Reset\n");
298 NoMaliGpu::setCallback(const nomali_callback_t
&callback
)
300 DPRINTF(NoMali
, "Registering callback %i\n",
304 nomali_set_callback(nomali
, &callback
),
305 "Failed to register callback");
309 NoMaliGpu::_interrupt(nomali_handle_t h
, void *usr
,
310 nomali_int_t intno
, int set
)
312 NoMaliGpu
*_this(static_cast<NoMaliGpu
*>(usr
));
314 _this
->onInterrupt(intno
, !!set
);
318 NoMaliGpu::_reset(nomali_handle_t h
, void *usr
)
320 NoMaliGpu
*_this(static_cast<NoMaliGpu
*>(usr
));
326 CustomNoMaliGpu::CustomNoMaliGpu(const CustomNoMaliGpuParams
*p
)
329 { GPU_CONTROL_REG(GPU_ID
), p
->gpu_id
},
330 { GPU_CONTROL_REG(L2_FEATURES
), p
->l2_features
},
331 { GPU_CONTROL_REG(TILER_FEATURES
), p
->tiler_features
},
332 { GPU_CONTROL_REG(MEM_FEATURES
), p
->mem_features
},
333 { GPU_CONTROL_REG(MMU_FEATURES
), p
->mmu_features
},
334 { GPU_CONTROL_REG(AS_PRESENT
), p
->as_present
},
335 { GPU_CONTROL_REG(JS_PRESENT
), p
->js_present
},
337 { GPU_CONTROL_REG(THREAD_MAX_THREADS
), p
->thread_max_threads
},
338 { GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE
),
339 p
->thread_max_workgroup_size
},
340 { GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE
),
341 p
->thread_max_barrier_size
},
342 { GPU_CONTROL_REG(THREAD_FEATURES
), p
->thread_features
},
344 { GPU_CONTROL_REG(SHADER_PRESENT_LO
), bits(p
->shader_present
, 31, 0) },
345 { GPU_CONTROL_REG(SHADER_PRESENT_HI
), bits(p
->shader_present
, 63, 32) },
346 { GPU_CONTROL_REG(TILER_PRESENT_LO
), bits(p
->tiler_present
, 31, 0) },
347 { GPU_CONTROL_REG(TILER_PRESENT_HI
), bits(p
->tiler_present
, 63, 32) },
348 { GPU_CONTROL_REG(L2_PRESENT_LO
), bits(p
->l2_present
, 31, 0) },
349 { GPU_CONTROL_REG(L2_PRESENT_HI
), bits(p
->l2_present
, 63, 32) },
352 fatal_if(p
->texture_features
.size() > 3,
353 "Too many texture feature registers specified (%i)\n",
354 p
->texture_features
.size());
356 fatal_if(p
->js_features
.size() > 16,
357 "Too many job slot feature registers specified (%i)\n",
358 p
->js_features
.size());
360 for (int i
= 0; i
< p
->texture_features
.size(); i
++)
361 idRegs
[TEXTURE_FEATURES_REG(i
)] = p
->texture_features
[i
];
363 for (int i
= 0; i
< p
->js_features
.size(); i
++)
364 idRegs
[JS_FEATURES_REG(i
)] = p
->js_features
[i
];
367 CustomNoMaliGpu::~CustomNoMaliGpu()
372 CustomNoMaliGpu::onReset()
374 NoMaliGpu::onReset();
376 for (const auto ®
: idRegs
)
377 writeRegRaw(reg
.first
, reg
.second
);
383 NoMaliGpuParams::create()
385 return new NoMaliGpu(this);
389 CustomNoMaliGpuParams::create()
391 return new CustomNoMaliGpu(this);