Files
beaglefw/omap35x.cc
Matthias Blankertz ba680cccdf -Added support for I2C module
-Initial support for TPS65950
-Support for changing CPU frequency in prcm driver
-Preparations for context switching
2013-07-12 20:29:34 +02:00

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();
}