blob: b8d8138e451606d144ee965d3d1f442e5baed1a3 [file] [log] [blame]
/*
* Copyright 2017, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
* See "LICENSE_BSD2.txt" for details.
*
* @TAG(DATA61_BSD)
*/
#include "src.h"
#define SLCR_PADDR 0xF8000000 /* System Level Control Registers */
#define SLCR_SIZE 0x1000
#define SLCR_LOCK_OFFSET 0x000 /* Offset of lock registers */
#define SLCR_CLK_OFFSET 0x100 /* Offset of clock registers */
#define LOCK_KEY 0x767B
#define UNLOCK_KEY 0xDF0D
#define SLCR_LOCKSTA_LOCKED BIT(0)
struct slcr_lock_regs {
uint32_t scl; /* 0x000 32 R/W 00000000h */
uint32_t lock; /* 0x004 32 W 00000000h */
uint32_t unlock; /* 0x008 32 W 00000000h */
uint32_t locksta; /* 0x008 32 R 00000001h */
};
typedef volatile struct slcr_lock_regs slcr_lock_regs_t;
struct slcr_regs {
slcr_lock_regs_t lock;
};
typedef volatile struct slcr_regs slcr_regs_t;
slcr_regs_t* slcr_regs;
static inline void
slcr_set_regs(src_dev_t* d, slcr_regs_t* r)
{
d->priv = (void*)r;
}
static inline slcr_regs_t*
slcr_get_regs(src_dev_t* d)
{
return (slcr_regs_t*)d->priv;
}
static inline int
reset_controller_unlock(src_dev_t* d)
{
slcr_regs_t* r = slcr_get_regs(d);
r->lock.unlock = UNLOCK_KEY;
return !(r->lock.locksta & SLCR_LOCKSTA_LOCKED);
}
static inline int
reset_controller_lock(src_dev_t* d)
{
slcr_regs_t* r = slcr_get_regs(d);
r->lock.lock = LOCK_KEY;
return !!(r->lock.locksta & SLCR_LOCKSTA_LOCKED);
}
void
reset_controller_assert_reset(src_dev_t* dev, enum src_rst_id id)
{
(void)dev;
(void)id;
}
void*
reset_controller_get_clock_regs(src_dev_t* dev)
{
void* slcr = (void*)slcr_get_regs(dev);
return (slcr + SLCR_CLK_OFFSET);
}
int
reset_controller_init(enum src_id id, ps_io_ops_t* ops, src_dev_t* dev)
{
/* Input bounds check */
if (id < 0 || id >= NSRC) {
return -1;
}
/* Map in the slcr registers */
slcr_regs = ps_io_map(&ops->io_mapper, SLCR_PADDR, SLCR_SIZE, 0, PS_MEM_NORMAL);
if (slcr_regs == NULL) {
return -1;
}
slcr_set_regs(dev, slcr_regs);
/* Unlock the reset controller registers */
reset_controller_unlock(dev);
return 0;
}