@@ -40,6 +40,7 @@ static int pmgr_initialized = 0;
4040
4141static int pmgr_path [8 ];
4242static int pmgr_offset ;
43+ static int pmgr_dies ;
4344
4445static const u32 * pmgr_ps_regs = NULL ;
4546static u32 pmgr_ps_regs_len = 0 ;
@@ -93,17 +94,19 @@ static int pmgr_find_device(u16 id, const struct pmgr_device **device)
9394 return -1 ;
9495}
9596
96- static uintptr_t pmgr_device_get_addr (const struct pmgr_device * device )
97+ static uintptr_t pmgr_device_get_addr (u8 die , const struct pmgr_device * device )
9798{
9899 uintptr_t addr = pmgr_get_psreg (device -> psreg_idx );
99100 if (addr == 0 )
100101 return 0 ;
101102
103+ addr += PMGR_DIE_OFFSET * die ;
104+
102105 addr += (device -> addr_offset << 3 );
103106 return addr ;
104107}
105108
106- static int pmgr_set_mode_recursive (u16 id , u8 target_mode , bool recurse )
109+ static int pmgr_set_mode_recursive (u8 die , u16 id , u8 target_mode , bool recurse )
107110{
108111 if (!pmgr_initialized ) {
109112 printf ("pmgr: pmgr_set_mode_recursive() called before successful pmgr_init()\n" );
@@ -119,7 +122,7 @@ static int pmgr_set_mode_recursive(u16 id, u8 target_mode, bool recurse)
119122 return -1 ;
120123
121124 if (!(device -> flags & PMGR_FLAG_VIRTUAL )) {
122- uintptr_t addr = pmgr_device_get_addr (device );
125+ uintptr_t addr = pmgr_device_get_addr (die , device );
123126 if (!addr )
124127 return -1 ;
125128 if (pmgr_set_mode (addr , target_mode ))
@@ -130,7 +133,8 @@ static int pmgr_set_mode_recursive(u16 id, u8 target_mode, bool recurse)
130133
131134 for (int i = 0 ; i < 2 ; i ++ ) {
132135 if (device -> parent [i ]) {
133- int ret = pmgr_set_mode_recursive (device -> parent [i ], target_mode , true);
136+ u16 parent = FIELD_GET (PMGR_DEVICE_ID , device -> parent [i ]);
137+ int ret = pmgr_set_mode_recursive (die , parent , target_mode , true);
134138 if (ret < 0 )
135139 return ret ;
136140 }
@@ -139,14 +143,18 @@ static int pmgr_set_mode_recursive(u16 id, u8 target_mode, bool recurse)
139143 return 0 ;
140144}
141145
142- int pmgr_power_enable (u16 id )
146+ int pmgr_power_enable (u32 id )
143147{
144- return pmgr_set_mode_recursive (id , PMGR_PS_ACTIVE , true);
148+ u16 device = FIELD_GET (PMGR_DEVICE_ID , id );
149+ u8 die = FIELD_GET (PMGR_DIE_ID , id );
150+ return pmgr_set_mode_recursive (die , device , PMGR_PS_ACTIVE , true);
145151}
146152
147- int pmgr_power_disable (u16 id )
153+ int pmgr_power_disable (u32 id )
148154{
149- return pmgr_set_mode_recursive (id , PMGR_PS_PWRGATE , false);
155+ u16 device = FIELD_GET (PMGR_DEVICE_ID , id );
156+ u8 die = FIELD_GET (PMGR_DIE_ID , id );
157+ return pmgr_set_mode_recursive (die , device , PMGR_PS_PWRGATE , false);
150158}
151159
152160static int pmgr_adt_find_devices (const char * path , const u32 * * devices , u32 * n_devices )
@@ -178,7 +186,9 @@ static int pmgr_adt_devices_set_mode(const char *path, u8 target_mode, int recur
178186 return -1 ;
179187
180188 for (u32 i = 0 ; i < n_devices ; ++ i ) {
181- if (pmgr_set_mode_recursive (devices [i ], target_mode , recurse ))
189+ u16 device = FIELD_GET (PMGR_DEVICE_ID , devices [i ]);
190+ u8 die = FIELD_GET (PMGR_DIE_ID , devices [i ]);
191+ if (pmgr_set_mode_recursive (die , device , target_mode , recurse ))
182192 ret = -1 ;
183193 }
184194
@@ -196,7 +206,7 @@ int pmgr_adt_power_disable(const char *path)
196206 return pmgr_adt_devices_set_mode (path , PMGR_PS_PWRGATE , false);
197207}
198208
199- int pmgr_reset (const char * name )
209+ int pmgr_reset (int die , const char * name )
200210{
201211 const struct pmgr_device * dev = NULL ;
202212
@@ -212,7 +222,12 @@ int pmgr_reset(const char *name)
212222 return -1 ;
213223 }
214224
215- uintptr_t addr = pmgr_device_get_addr (dev );
225+ if (die < 0 || die > 16 ) {
226+ printf ("pmgr: invalid die id %d for devicece %s\n" , die , name );
227+ return -1 ;
228+ }
229+
230+ uintptr_t addr = pmgr_device_get_addr (die , dev );
216231
217232 u32 reg = read32 (addr );
218233 if (FIELD_GET (PMGR_PS_ACTUAL , reg ) != PMGR_PS_ACTIVE ) {
@@ -231,6 +246,14 @@ int pmgr_reset(const char *name)
231246
232247int pmgr_init (void )
233248{
249+ int node = adt_path_offset (adt , "/arm-io" );
250+ if (node < 0 ) {
251+ printf ("pmgr: Error getting /arm-io node\n" );
252+ return -1 ;
253+ }
254+ if (ADT_GETPROP (adt , node , "die-count" , & pmgr_dies ) < 0 )
255+ pmgr_dies = 1 ;
256+
234257 pmgr_offset = adt_path_offset_trace (adt , "/arm-io/pmgr" , pmgr_path );
235258 if (pmgr_offset < 0 ) {
236259 printf ("pmgr: Error getting /arm-io/pmgr node\n" );
@@ -254,49 +277,51 @@ int pmgr_init(void)
254277
255278 printf ("pmgr: Cleaning up device states...\n" );
256279
257- for (size_t i = 0 ; i < pmgr_devices_len ; ++ i ) {
258- const struct pmgr_device * device = & pmgr_devices [i ];
280+ for (u8 die = 0 ; die < pmgr_dies ; ++ die ) {
281+ for (size_t i = 0 ; i < pmgr_devices_len ; ++ i ) {
282+ const struct pmgr_device * device = & pmgr_devices [i ];
259283
260- if ((device -> flags & PMGR_FLAG_VIRTUAL ))
261- continue ;
284+ if ((device -> flags & PMGR_FLAG_VIRTUAL ))
285+ continue ;
262286
263- uintptr_t addr = pmgr_device_get_addr (device );
264- if (!addr )
265- continue ;
287+ uintptr_t addr = pmgr_device_get_addr (die , device );
288+ if (!addr )
289+ continue ;
266290
267- u32 reg = read32 (addr );
291+ u32 reg = read32 (addr );
268292
269- if (reg & PMGR_AUTO_ENABLE || FIELD_GET (PMGR_PS_TARGET , reg ) == PMGR_PS_ACTIVE ) {
270- for (int j = 0 ; j < 2 ; j ++ ) {
271- if (device -> parent [j ]) {
272- const struct pmgr_device * pdevice ;
273- if (pmgr_find_device (device -> parent [j ], & pdevice )) {
274- printf ("pmgr: Failed to find parent #%d for %s\n" , device -> parent [j ],
275- device -> name );
276- continue ;
277- }
293+ if (reg & PMGR_AUTO_ENABLE || FIELD_GET (PMGR_PS_TARGET , reg ) == PMGR_PS_ACTIVE ) {
294+ for (int j = 0 ; j < 2 ; j ++ ) {
295+ if (device -> parent [j ]) {
296+ const struct pmgr_device * pdevice ;
297+ if (pmgr_find_device (device -> parent [j ], & pdevice )) {
298+ printf ("pmgr: Failed to find parent #%d for %s\n" , device -> parent [j ],
299+ device -> name );
300+ continue ;
301+ }
278302
279- if ((pdevice -> flags & PMGR_FLAG_VIRTUAL ))
280- continue ;
303+ if ((pdevice -> flags & PMGR_FLAG_VIRTUAL ))
304+ continue ;
281305
282- addr = pmgr_device_get_addr (pdevice );
283- if (!addr )
284- continue ;
306+ addr = pmgr_device_get_addr (die , pdevice );
307+ if (!addr )
308+ continue ;
285309
286- reg = read32 (addr );
310+ reg = read32 (addr );
287311
288- if (!(reg & PMGR_AUTO_ENABLE ) &&
289- FIELD_GET (PMGR_PS_TARGET , reg ) != PMGR_PS_ACTIVE ) {
290- printf ("pmgr: Enabling %s, parent of active device %s\n" , pdevice -> name ,
291- device -> name );
292- pmgr_set_mode (addr , PMGR_PS_ACTIVE );
312+ if (!(reg & PMGR_AUTO_ENABLE ) &&
313+ FIELD_GET (PMGR_PS_TARGET , reg ) != PMGR_PS_ACTIVE ) {
314+ printf ("pmgr: Enabling %d.%s, parent of active device %s\n" , die ,
315+ pdevice -> name , device -> name );
316+ pmgr_set_mode (addr , PMGR_PS_ACTIVE );
317+ }
293318 }
294319 }
295320 }
296321 }
297322 }
298323
299- printf ("pmgr: initialized, %d devices found.\n" , pmgr_devices_len );
324+ printf ("pmgr: initialized, %d devices on %u dies found.\n" , pmgr_devices_len , pmgr_dies );
300325
301326 return 0 ;
302327}
0 commit comments