-Initial support for TPS65950 -Support for changing CPU frequency in prcm driver -Preparations for context switching
100 lines
2.6 KiB
C++
100 lines
2.6 KiB
C++
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cassert>
|
|
|
|
#include "util.hh"
|
|
#include "mmio.hh"
|
|
#include "omap35x.hh"
|
|
|
|
using std::printf;
|
|
|
|
static const char *const omap_names[5] = {"OMAP3530", "OMAP3525", "OMAP3515", "OMAP3503", "UNKNOWN"};
|
|
static const char *const omap_ver[8] = {"ES 1.0", "ES 2.0", "ES 2.1", "ES 3.0", "ES 3.1", "UNKNOWN", "UNKNOWN", "ES 3.1.2"};
|
|
|
|
static std::array<uint32_t, 4> qemu_serial = {0x51454d55, 0x51454d55, 0x54000000, 0x51454d55};
|
|
|
|
class OMAP35x_Info_impl {
|
|
public:
|
|
OMAP35x_Info_impl(uintptr_t scm_base, uintptr_t control_base)
|
|
: scm_base_{scm_base}, control_base_{control_base}, serial_(_get_serial()) {
|
|
}
|
|
|
|
~OMAP35x_Info_impl() {
|
|
}
|
|
|
|
void print_chip_id() {
|
|
uint16_t omapsr = r_omap_sr()&0xffffu;
|
|
int omapsr_idx;
|
|
switch(omapsr) {
|
|
case 0x0c00:
|
|
omapsr_idx = 0;
|
|
break;
|
|
case 0x4c00:
|
|
omapsr_idx = 1;
|
|
break;
|
|
case 0x1c00:
|
|
omapsr_idx = 2;
|
|
break;
|
|
case 0x5c00:
|
|
omapsr_idx = 3;
|
|
break;
|
|
default:
|
|
printf("Warning: Unknown OMAP35x type (%.8lx)\n", r_omap_sr());
|
|
omapsr_idx = 4;
|
|
break;
|
|
}
|
|
|
|
uint32_t idcode = r_idcode();
|
|
int id_idx = (idcode&0xf0000000u)>>28;
|
|
if(id_idx > 7) // Versions 8..15 are unknown
|
|
id_idx = 6;
|
|
if(id_idx == 5 || id_idx == 6)
|
|
printf("Warning: Unknown OMAP35x version (%.8lx)\n", idcode);
|
|
|
|
bool highfreq = false;
|
|
if((r_skuid()&0xf) == 0x8)
|
|
highfreq = true;
|
|
|
|
printf("%s %s %s Serial# %.8lx%.8lx%.8lx%.8lx\n",
|
|
omap_names[omapsr_idx], omap_ver[id_idx],
|
|
highfreq?"720 MHz":"600 MHz",
|
|
serial_[0], serial_[1], serial_[2], serial_[3]);
|
|
}
|
|
|
|
bool running_on_qemu() const {
|
|
return (serial_ == qemu_serial);
|
|
}
|
|
|
|
std::array<uint32_t, 4> const& get_serial() const {
|
|
return serial_;
|
|
}
|
|
|
|
private:
|
|
std::array<uint32_t, 4> _get_serial() {
|
|
return std::array<uint32_t, 4>{r_die_id(3), r_die_id(2), r_die_id(1), r_die_id(0)};
|
|
}
|
|
|
|
MMIO_alloc scm_base_, control_base_;
|
|
std::array<uint32_t, 4> serial_;
|
|
|
|
uint32_t volatile& r_omap_sr() { return _reg32(scm_base_.get_virt(), 0x44c); }
|
|
uint32_t volatile& r_idcode() { return _reg32(control_base_.get_virt(), 0x204); }
|
|
uint32_t volatile& r_die_id(int n) { assert(n >= 0 && n <= 3); return _reg32(control_base_.get_virt(), 0x218+0x4*n); }
|
|
uint32_t volatile& r_skuid() { return _reg32(control_base_.get_virt(), 0x20c); }
|
|
};
|
|
|
|
|
|
OMAP35x_Info::OMAP35x_Info(uintptr_t scm_base, uintptr_t control_base) : impl_{new OMAP35x_Info_impl{scm_base, control_base}} {
|
|
}
|
|
|
|
OMAP35x_Info::~OMAP35x_Info() {
|
|
}
|
|
|
|
void OMAP35x_Info::print_chip_id() {
|
|
impl_->print_chip_id();
|
|
}
|
|
|
|
bool OMAP35x_Info::running_on_qemu() const {
|
|
return impl_->running_on_qemu();
|
|
}
|