112077Sgedare@rtems.org/*
212077Sgedare@rtems.org * Copyright (c) 2017 Gedare Bloom
312077Sgedare@rtems.org * Copyright (c) 2010 ARM Limited
412077Sgedare@rtems.org * All rights reserved
512077Sgedare@rtems.org *
612077Sgedare@rtems.org * The license below extends only to copyright in the software and shall
712077Sgedare@rtems.org * not be construed as granting a license to any other intellectual
812077Sgedare@rtems.org * property including but not limited to intellectual property relating
912077Sgedare@rtems.org * to a hardware implementation of the functionality of the software
1012077Sgedare@rtems.org * licensed hereunder.  You may use the software subject to the license
1112077Sgedare@rtems.org * terms below provided that you ensure that this notice is replicated
1212077Sgedare@rtems.org * unmodified and in its entirety in all distributions of the software,
1312077Sgedare@rtems.org * modified or unmodified, in source code or in binary form.
1412077Sgedare@rtems.org *
1512077Sgedare@rtems.org * Redistribution and use in source and binary forms, with or without
1612077Sgedare@rtems.org * modification, are permitted provided that the following conditions are
1712077Sgedare@rtems.org * met: redistributions of source code must retain the above copyright
1812077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer;
1912077Sgedare@rtems.org * redistributions in binary form must reproduce the above copyright
2012077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer in the
2112077Sgedare@rtems.org * documentation and/or other materials provided with the distribution;
2212077Sgedare@rtems.org * neither the name of the copyright holders nor the names of its
2312077Sgedare@rtems.org * contributors may be used to endorse or promote products derived from
2412077Sgedare@rtems.org * this software without specific prior written permission.
2512077Sgedare@rtems.org *
2612077Sgedare@rtems.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2712077Sgedare@rtems.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2812077Sgedare@rtems.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2912077Sgedare@rtems.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3012077Sgedare@rtems.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3112077Sgedare@rtems.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3212077Sgedare@rtems.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3312077Sgedare@rtems.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3412077Sgedare@rtems.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3512077Sgedare@rtems.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3612077Sgedare@rtems.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3712077Sgedare@rtems.org *
3812077Sgedare@rtems.org * Authors: Ali Saidi
3912077Sgedare@rtems.org *          Gedare Bloom
4012077Sgedare@rtems.org */
4112077Sgedare@rtems.org
4212077Sgedare@rtems.org#ifndef __DEV_ARM_GLOBAL_TIMER_HH__
4312077Sgedare@rtems.org#define __DEV_ARM_GLOBAL_TIMER_HH__
4412077Sgedare@rtems.org
4512077Sgedare@rtems.org#include "dev/io_device.hh"
4612077Sgedare@rtems.org#include "params/A9GlobalTimer.hh"
4712077Sgedare@rtems.org
4812077Sgedare@rtems.org/** @file
4912077Sgedare@rtems.org * This implements the Cortex A9-MPCore global timer from TRM rev r4p1.
5012077Sgedare@rtems.org * The global timer is an incrementing timer.
5112077Sgedare@rtems.org */
5212077Sgedare@rtems.org
5312077Sgedare@rtems.orgclass BaseGic;
5412077Sgedare@rtems.org
5512077Sgedare@rtems.orgclass A9GlobalTimer : public BasicPioDevice
5612077Sgedare@rtems.org{
5712077Sgedare@rtems.org  protected:
5812077Sgedare@rtems.org    class Timer : public Serializable
5912077Sgedare@rtems.org    {
6012077Sgedare@rtems.org
6112077Sgedare@rtems.org      public:
6212077Sgedare@rtems.org        /* TODO: IntStatusReg, CmpValRegLow32, CmpValRegHigh32,
6312077Sgedare@rtems.org         * and AutoIncrementReg are banked per-cpu. Some bits of
6412077Sgedare@rtems.org         * ControlReg are also banked per-cpu, see below. */
6512077Sgedare@rtems.org        enum {
6612077Sgedare@rtems.org            CounterRegLow32  = 0x00,
6712077Sgedare@rtems.org            CounterRegHigh32 = 0x04,
6812077Sgedare@rtems.org            ControlReg       = 0x08,
6912077Sgedare@rtems.org            IntStatusReg     = 0x0C,
7012077Sgedare@rtems.org            CmpValRegLow32   = 0x10,
7112077Sgedare@rtems.org            CmpValRegHigh32  = 0x14,
7212077Sgedare@rtems.org            AutoIncrementReg = 0x18,
7312077Sgedare@rtems.org            Size             = 0x1C
7412077Sgedare@rtems.org        };
7512077Sgedare@rtems.org
7612077Sgedare@rtems.org        /* TODO: bits 1--3 are banked per-cpu */
7712077Sgedare@rtems.org        BitUnion32(CTRL)
7812077Sgedare@rtems.org            Bitfield<0>    enable;
7912077Sgedare@rtems.org            Bitfield<1>    cmpEnable;
8012077Sgedare@rtems.org            Bitfield<2>    intEnable;
8112077Sgedare@rtems.org            Bitfield<3>    autoIncrement;
8212077Sgedare@rtems.org            Bitfield<7,4>  reserved;
8312077Sgedare@rtems.org            Bitfield<15,8> prescalar;
8412077Sgedare@rtems.org        EndBitUnion(CTRL)
8512077Sgedare@rtems.org
8612077Sgedare@rtems.org      protected:
8712077Sgedare@rtems.org        std::string _name;
8812077Sgedare@rtems.org
8912077Sgedare@rtems.org        /** Pointer to parent class */
9012077Sgedare@rtems.org        A9GlobalTimer *parent;
9112077Sgedare@rtems.org
9212077Sgedare@rtems.org        /** Number of interrupt to cause/clear */
9312077Sgedare@rtems.org        const uint32_t intNum;
9412077Sgedare@rtems.org
9512077Sgedare@rtems.org        /** Control register as specified above */
9612077Sgedare@rtems.org        /* TODO: one per-cpu? */
9712077Sgedare@rtems.org        CTRL control;
9812077Sgedare@rtems.org
9912077Sgedare@rtems.org        /** If timer has caused an interrupt. This is irrespective of
10012077Sgedare@rtems.org         * interrupt enable */
10112077Sgedare@rtems.org        /* TODO: one per-cpu */
10212077Sgedare@rtems.org        bool rawInt;
10312077Sgedare@rtems.org
10412077Sgedare@rtems.org        /** If an interrupt is currently pending. Logical and of CTRL.intEnable
10512077Sgedare@rtems.org         * and rawInt */
10612077Sgedare@rtems.org        bool pendingInt;
10712077Sgedare@rtems.org
10812077Sgedare@rtems.org        /** Value of the comparator */
10912077Sgedare@rtems.org        uint64_t cmpVal;
11012077Sgedare@rtems.org
11112077Sgedare@rtems.org        /** Value to add to comparator when counter reaches comparator */
11212077Sgedare@rtems.org        /* TODO: one per-cpu */
11312077Sgedare@rtems.org        uint32_t autoIncValue;
11412077Sgedare@rtems.org
11512077Sgedare@rtems.org        /** Called when the counter reaches the comparator */
11612077Sgedare@rtems.org        void counterAtCmpVal();
11712077Sgedare@rtems.org        EventWrapper<Timer, &Timer::counterAtCmpVal> cmpValEvent;
11812077Sgedare@rtems.org
11912077Sgedare@rtems.org      public:
12012077Sgedare@rtems.org        /** Restart the counter ticking */
12112077Sgedare@rtems.org        void restartCounter();
12212077Sgedare@rtems.org        /**
12312077Sgedare@rtems.org          * Convert a number of ticks into the time counter format
12412077Sgedare@rtems.org          * @param ticks number of ticks
12512077Sgedare@rtems.org          */
12612077Sgedare@rtems.org        uint64_t getTimeCounterFromTicks(Tick ticks);
12712077Sgedare@rtems.org        Timer(std::string __name, A9GlobalTimer *parent, int int_num);
12812077Sgedare@rtems.org
12912077Sgedare@rtems.org        std::string name() const { return _name; }
13012077Sgedare@rtems.org
13112077Sgedare@rtems.org        /** Handle read for a single timer */
13212077Sgedare@rtems.org        void read(PacketPtr pkt, Addr daddr);
13312077Sgedare@rtems.org
13412077Sgedare@rtems.org        /** Handle write for a single timer */
13512077Sgedare@rtems.org        void write(PacketPtr pkt, Addr daddr);
13612077Sgedare@rtems.org
13712077Sgedare@rtems.org        void serialize(CheckpointOut &cp) const override;
13812077Sgedare@rtems.org        void unserialize(CheckpointIn &cp) override;
13912077Sgedare@rtems.org    };
14012077Sgedare@rtems.org
14112077Sgedare@rtems.org    /** Pointer to the GIC for causing an interrupt */
14212077Sgedare@rtems.org    BaseGic *gic;
14312077Sgedare@rtems.org
14412077Sgedare@rtems.org    /** Timer that does the actual work */
14512077Sgedare@rtems.org    Timer global_timer;
14612077Sgedare@rtems.org
14712077Sgedare@rtems.org  public:
14812077Sgedare@rtems.org    typedef A9GlobalTimerParams Params;
14912077Sgedare@rtems.org    const Params *
15012077Sgedare@rtems.org    params() const
15112077Sgedare@rtems.org    {
15212077Sgedare@rtems.org        return dynamic_cast<const Params *>(_params);
15312077Sgedare@rtems.org    }
15412077Sgedare@rtems.org    /**
15512077Sgedare@rtems.org      * The constructor for RealView just registers itself with the MMU.
15612077Sgedare@rtems.org      * @param p params structure
15712077Sgedare@rtems.org      */
15812077Sgedare@rtems.org    A9GlobalTimer(Params *p);
15912077Sgedare@rtems.org
16012077Sgedare@rtems.org    /**
16112077Sgedare@rtems.org     * Handle a read to the device
16212077Sgedare@rtems.org     * @param pkt The memory request.
16312077Sgedare@rtems.org     * @return Returns latency of device read
16412077Sgedare@rtems.org     */
16512077Sgedare@rtems.org    Tick read(PacketPtr pkt) override;
16612077Sgedare@rtems.org
16712077Sgedare@rtems.org    /**
16812077Sgedare@rtems.org     * Handle a write to the device.
16912077Sgedare@rtems.org     * @param pkt The memory request.
17012077Sgedare@rtems.org     * @return Returns latency of device write
17112077Sgedare@rtems.org     */
17212077Sgedare@rtems.org    Tick write(PacketPtr pkt) override;
17312077Sgedare@rtems.org
17412077Sgedare@rtems.org    void serialize(CheckpointOut &cp) const override;
17512077Sgedare@rtems.org    void unserialize(CheckpointIn &cp) override;
17612077Sgedare@rtems.org};
17712077Sgedare@rtems.org
17812077Sgedare@rtems.org#endif // __DEV_ARM_GLOBAL_TIMER_HH__
179