Statistics
| Branch: | Revision:

root / hw / puv3_pm.c @ 0d09e41a

History | View | Annotate | Download (3.3 kB)

1
/*
2
 * Power Management device simulation in PKUnity SoC
3
 *
4
 * Copyright (C) 2010-2012 Guan Xuetao
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License version 2 as
8
 * published by the Free Software Foundation, or any later version.
9
 * See the COPYING file in the top-level directory.
10
 */
11
#include "hw/hw.h"
12
#include "hw/sysbus.h"
13

    
14
#undef DEBUG_PUV3
15
#include "hw/unicore32/puv3.h"
16

    
17
typedef struct {
18
    SysBusDevice busdev;
19
    MemoryRegion iomem;
20

    
21
    uint32_t reg_PMCR;
22
    uint32_t reg_PCGR;
23
    uint32_t reg_PLL_SYS_CFG;
24
    uint32_t reg_PLL_DDR_CFG;
25
    uint32_t reg_PLL_VGA_CFG;
26
    uint32_t reg_DIVCFG;
27
} PUV3PMState;
28

    
29
static uint64_t puv3_pm_read(void *opaque, hwaddr offset,
30
        unsigned size)
31
{
32
    PUV3PMState *s = opaque;
33
    uint32_t ret = 0;
34

    
35
    switch (offset) {
36
    case 0x14:
37
        ret = s->reg_PCGR;
38
        break;
39
    case 0x18:
40
        ret = s->reg_PLL_SYS_CFG;
41
        break;
42
    case 0x1c:
43
        ret = s->reg_PLL_DDR_CFG;
44
        break;
45
    case 0x20:
46
        ret = s->reg_PLL_VGA_CFG;
47
        break;
48
    case 0x24:
49
        ret = s->reg_DIVCFG;
50
        break;
51
    case 0x28: /* PLL SYS STATUS */
52
        ret = 0x00002401;
53
        break;
54
    case 0x2c: /* PLL DDR STATUS */
55
        ret = 0x00100c00;
56
        break;
57
    case 0x30: /* PLL VGA STATUS */
58
        ret = 0x00003801;
59
        break;
60
    case 0x34: /* DIV STATUS */
61
        ret = 0x22f52015;
62
        break;
63
    case 0x38: /* SW RESET */
64
        ret = 0x0;
65
        break;
66
    case 0x44: /* PLL DFC DONE */
67
        ret = 0x7;
68
        break;
69
    default:
70
        DPRINTF("Bad offset 0x%x\n", offset);
71
    }
72
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
73

    
74
    return ret;
75
}
76

    
77
static void puv3_pm_write(void *opaque, hwaddr offset,
78
        uint64_t value, unsigned size)
79
{
80
    PUV3PMState *s = opaque;
81

    
82
    switch (offset) {
83
    case 0x0:
84
        s->reg_PMCR = value;
85
        break;
86
    case 0x14:
87
        s->reg_PCGR = value;
88
        break;
89
    case 0x18:
90
        s->reg_PLL_SYS_CFG = value;
91
        break;
92
    case 0x1c:
93
        s->reg_PLL_DDR_CFG = value;
94
        break;
95
    case 0x20:
96
        s->reg_PLL_VGA_CFG = value;
97
        break;
98
    case 0x24:
99
    case 0x38:
100
        break;
101
    default:
102
        DPRINTF("Bad offset 0x%x\n", offset);
103
    }
104
    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
105
}
106

    
107
static const MemoryRegionOps puv3_pm_ops = {
108
    .read = puv3_pm_read,
109
    .write = puv3_pm_write,
110
    .impl = {
111
        .min_access_size = 4,
112
        .max_access_size = 4,
113
    },
114
    .endianness = DEVICE_NATIVE_ENDIAN,
115
};
116

    
117
static int puv3_pm_init(SysBusDevice *dev)
118
{
119
    PUV3PMState *s = FROM_SYSBUS(PUV3PMState, dev);
120

    
121
    s->reg_PCGR = 0x0;
122

    
123
    memory_region_init_io(&s->iomem, &puv3_pm_ops, s, "puv3_pm",
124
            PUV3_REGS_OFFSET);
125
    sysbus_init_mmio(dev, &s->iomem);
126

    
127
    return 0;
128
}
129

    
130
static void puv3_pm_class_init(ObjectClass *klass, void *data)
131
{
132
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
133

    
134
    sdc->init = puv3_pm_init;
135
}
136

    
137
static const TypeInfo puv3_pm_info = {
138
    .name = "puv3_pm",
139
    .parent = TYPE_SYS_BUS_DEVICE,
140
    .instance_size = sizeof(PUV3PMState),
141
    .class_init = puv3_pm_class_init,
142
};
143

    
144
static void puv3_pm_register_type(void)
145
{
146
    type_register_static(&puv3_pm_info);
147
}
148

    
149
type_init(puv3_pm_register_type)