Commit f5470d2b4740ea5f99a581375d60fd19cb74657d

Authored by Evgeniy Dushistov
1 parent 6abe522c

PMC:

- read from some of pmc registers return 0,
but it not should work in so way, because of for example linux kernel
expect proper values there, and 0 cause divide by zero exception

- convert main oscilator freq from constant to device property
Showing 2 changed files with 26 additions and 4 deletions
hw/at91_pmc.c
@@ -55,7 +55,6 @@ @@ -55,7 +55,6 @@
55 #define SR_PCK3RDY 0x800 55 #define SR_PCK3RDY 0x800
56 56
57 #define SO_FREQ 32768 57 #define SO_FREQ 32768
58 -#define MO_FREQ 9216000  
59 58
60 int at91_master_clock_frequency = SO_FREQ; 59 int at91_master_clock_frequency = SO_FREQ;
61 60
@@ -72,6 +71,7 @@ typedef struct PMCState { @@ -72,6 +71,7 @@ typedef struct PMCState {
72 uint32_t sr; 71 uint32_t sr;
73 uint32_t imr; 72 uint32_t imr;
74 uint32_t mck_freq; 73 uint32_t mck_freq;
  74 + uint32_t mo_freq;
75 } PMCState; 75 } PMCState;
76 76
77 static void at91_pmc_update_irq(PMCState *s) 77 static void at91_pmc_update_irq(PMCState *s)
@@ -81,7 +81,7 @@ static void at91_pmc_update_irq(PMCState *s) @@ -81,7 +81,7 @@ static void at91_pmc_update_irq(PMCState *s)
81 81
82 static void at91_update_master_clock(PMCState *s) 82 static void at91_update_master_clock(PMCState *s)
83 { 83 {
84 - int mck_freq = MO_FREQ; 84 + int mck_freq = s->mo_freq;
85 85
86 /* Clock selection */ 86 /* Clock selection */
87 switch (s->mckr & 3) { 87 switch (s->mckr & 3) {
@@ -128,6 +128,10 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset) @@ -128,6 +128,10 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset)
128 PMCState *s = opaque; 128 PMCState *s = opaque;
129 129
130 switch (offset) { 130 switch (offset) {
  131 + case PMC_PLLA:
  132 + return s->plla;
  133 + case PMC_PLLB:
  134 + return s->pllb;
131 case PMC_SCSR: 135 case PMC_SCSR:
132 return s->scsr; 136 return s->scsr;
133 case PMC_PCSR: 137 case PMC_PCSR:
@@ -136,7 +140,7 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset) @@ -136,7 +140,7 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset)
136 return s->mor; 140 return s->mor;
137 case PMC_MCFR: 141 case PMC_MCFR:
138 if (s->mor & 1) 142 if (s->mor & 1)
139 - return (1 << 16) | (MO_FREQ / SO_FREQ / 16); 143 + return (1 << 16) | (s->mo_freq / SO_FREQ / 16);
140 return 0; 144 return 0;
141 case PMC_PCKR ... PMC_PCKR + 15: 145 case PMC_PCKR ... PMC_PCKR + 15:
142 return s->pckr[(offset - PMC_PCKR) >> 2]; 146 return s->pckr[(offset - PMC_PCKR) >> 2];
@@ -144,6 +148,8 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset) @@ -144,6 +148,8 @@ static uint32_t at91_pmc_mem_read(void *opaque, target_phys_addr_t offset)
144 return s->sr; 148 return s->sr;
145 case PMC_IMR: 149 case PMC_IMR:
146 return s->imr; 150 return s->imr;
  151 + case PMC_MCKR:
  152 + return s->mckr;
147 default: 153 default:
148 return 0; 154 return 0;
149 } 155 }
@@ -290,9 +296,24 @@ static void at91_pmc_init(SysBusDevice *dev) @@ -290,9 +296,24 @@ static void at91_pmc_init(SysBusDevice *dev)
290 register_savevm("at91_pmc", -1, 1, at91_pmc_save, at91_pmc_load, s); 296 register_savevm("at91_pmc", -1, 1, at91_pmc_save, at91_pmc_load, s);
291 } 297 }
292 298
  299 +static SysBusDeviceInfo pmc_info = {
  300 + .init = at91_pmc_init,
  301 + .qdev.name = "at91,pmc",
  302 + .qdev.size = sizeof(PMCState),
  303 + .qdev.props = (Property[]) {
  304 + {
  305 + .name = "mo_freq",
  306 + .info = &qdev_prop_uint32,
  307 + .offset = offsetof(PMCState, mo_freq),
  308 + .defval = (uint32_t[]) { 0 },
  309 + },
  310 + {/* end of list */}
  311 + }
  312 +};
  313 +
293 static void at91_pmc_register(void) 314 static void at91_pmc_register(void)
294 { 315 {
295 - sysbus_register_dev("at91,pmc", sizeof(PMCState), at91_pmc_init); 316 + sysbus_register_withprop(&pmc_info);
296 } 317 }
297 318
298 device_init(at91_pmc_register) 319 device_init(at91_pmc_register)
hw/at91pes.c
@@ -81,6 +81,7 @@ static void at91pes_init(ram_addr_t ram_size, @@ -81,6 +81,7 @@ static void at91pes_init(ram_addr_t ram_size,
81 81
82 sysbus_create_simple("at91,dbgu", 0xFFFFF200, pic1[0]); 82 sysbus_create_simple("at91,dbgu", 0xFFFFF200, pic1[0]);
83 pmc = sysbus_create_simple("at91,pmc", 0xFFFFFC00, pic1[1]); 83 pmc = sysbus_create_simple("at91,pmc", 0xFFFFFC00, pic1[1]);
  84 + qdev_prop_set_uint32(pmc, "mo_freq", 9216000);
84 sysbus_create_varargs("at91,rstc", 0xFFFFFD00, NULL); 85 sysbus_create_varargs("at91,rstc", 0xFFFFFD00, NULL);
85 pioa = sysbus_create_simple("at91,pio", 0xFFFFF400, pic[2]); 86 pioa = sysbus_create_simple("at91,pio", 0xFFFFF400, pic[2]);
86 piob = sysbus_create_simple("at91,pio", 0xFFFFF600, pic[3]); 87 piob = sysbus_create_simple("at91,pio", 0xFFFFF600, pic[3]);