From d17529b046d832f889a0fdb506c3b8d1aed5cccb Mon Sep 17 00:00:00 2001 From: Matt Evans Date: Thu, 31 Oct 2013 13:41:13 -0500 Subject: dev: Add 'OSC' oscillator sys control reg support to VersatileExpress The VE motherboard provides a set of system control registers through which various motherboard and coretile registers are accessed. Voltage regulators and oscillator (DLL/PLL) config are examples. These registers must be impleted to boot Linux 3.9+ kernels. --- src/dev/arm/SConscript | 1 + src/dev/arm/rv_ctrl.cc | 108 +++++++++++++++++++++++++++++++++++++++++++++++-- src/dev/arm/rv_ctrl.hh | 10 +++-- 3 files changed, 112 insertions(+), 7 deletions(-) (limited to 'src/dev') diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript index 60a85220e..68779ec64 100644 --- a/src/dev/arm/SConscript +++ b/src/dev/arm/SConscript @@ -63,3 +63,4 @@ if env['TARGET_ISA'] == 'arm': DebugFlag('PL111') DebugFlag('Pl050') DebugFlag('GIC') + DebugFlag('RVCTRL') diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc index 61111d22e..af121861c 100644 --- a/src/dev/arm/rv_ctrl.cc +++ b/src/dev/arm/rv_ctrl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010,2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -38,12 +38,13 @@ */ #include "base/trace.hh" +#include "debug/RVCTRL.hh" #include "dev/arm/rv_ctrl.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" RealViewCtrl::RealViewCtrl(Params *p) - : BasicPioDevice(p, 0xD4), flags(0) + : BasicPioDevice(p, 0xD4), flags(0), scData(0) { } @@ -105,9 +106,18 @@ RealViewCtrl::read(PacketPtr pkt) case CfgStat: pkt->set(1); break; + case CfgData: + pkt->set(scData); + DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData); + break; + case CfgCtrl: + pkt->set(0); // not busy + DPRINTF(RVCTRL, "Read 0 from CfgCtrl\n"); + break; default: warn("Tried to read RealView I/O at offset %#x that doesn't exist\n", daddr); + pkt->set(0); break; } pkt->makeAtomicResponse(); @@ -139,9 +149,99 @@ RealViewCtrl::write(PacketPtr pkt) case FlagsClr: flags = 0; break; + case CfgData: + scData = pkt->get(); + break; + case CfgCtrl: { + // A request is being submitted to read/write the system control + // registers. See + // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html + // For now, model as much of the OSC regs (can't find docs) as Linux + // seems to require (can't find docs); some clocks are deemed to be 0, + // giving all kinds of /0 problems booting Linux 3.9. Return a + // vaguely plausible number within the range the device trees state: + uint32_t data = pkt->get(); + uint16_t dev = bits(data, 11, 0); + uint8_t pos = bits(data, 15, 12); + uint8_t site = bits(data, 17, 16); + uint8_t func = bits(data, 25, 20); + uint8_t dcc = bits(data, 29, 26); + bool wr = bits(data, 30); + bool start = bits(data, 31); + + if (start) { + if (wr) { + warn_once("SCReg: Writing %#x to dcc%d:site%d:pos%d:fn%d:dev%d\n", + scData, dcc, site, pos, func, dev); + // Only really support reading, for now! + } else { + // Only deal with function 1 (oscillators) so far! + if (dcc != 0 || pos != 0 || func != 1) { + warn("SCReg: read from unknown area " + "(dcc %d:site%d:pos%d:fn%d:dev%d)\n", + dcc, site, pos, func, dev); + } else { + switch (site) { + case 0: { // Motherboard regs + switch(dev) { + case 0: // MCC clk + scData = 25000000; + break; + case 1: // CLCD clk + scData = 25000000; + break; + case 2: // PeriphClk 24MHz + scData = 24000000; + break; + default: + scData = 0; + warn("SCReg: read from unknown dev %d " + "(site%d:pos%d:fn%d)\n", + dev, site, pos, func); + } + } break; + case 1: { // Coretile 1 regs + switch(dev) { + case 0: // CPU PLL ref + scData = 50000000; + break; + case 4: // Muxed AXI master clock + scData = 40000000; + break; + case 5: // HDLCD clk + scData = 50000000; + break; + case 6: // SMB clock + scData = 35000000; + break; + case 7: // SYS PLL (also used for pl011 UART!) + scData = 40000000; + break; + case 8: // DDR PLL 40MHz fixed + scData = 40000000; + break; + default: + scData = 0; + warn("SCReg: read from unknown dev %d " + "(site%d:pos%d:fn%d)\n", + dev, site, pos, func); + } + } break; + default: + warn("SCReg: Read from unknown site %d (pos%d:fn%d:dev%d)\n", + site, pos, func, dev); + } + DPRINTF(RVCTRL, "SCReg: Will read %#x (ctrlWr %#x)\n", scData, data); + } + } + } else { + DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n", data); + } + } break; + case CfgStat: // Weird to write this default: - warn("Tried to write RVIO at offset %#x that doesn't exist\n", - daddr); + warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n", + daddr, pkt->get()); break; } pkt->makeAtomicResponse(); diff --git a/src/dev/arm/rv_ctrl.hh b/src/dev/arm/rv_ctrl.hh index c6cf40f96..adf065631 100644 --- a/src/dev/arm/rv_ctrl.hh +++ b/src/dev/arm/rv_ctrl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010,2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -80,8 +80,8 @@ class RealViewCtrl : public BasicPioDevice IoSel = 0x70, ProcId0 = 0x84, ProcId1 = 0x88, - CfgCtrl = 0xA0, - CfgData = 0xA4, + CfgData = 0xA0, + CfgCtrl = 0xA4, CfgStat = 0xA8, TestOsc0 = 0xC0, TestOsc1 = 0xC4, @@ -105,6 +105,10 @@ class RealViewCtrl : public BasicPioDevice */ uint32_t flags; + /** This register contains the result from a system control reg access + */ + uint32_t scData; + public: typedef RealViewCtrlParams Params; const Params * -- cgit v1.2.3