16
16
#include "hw/irq.h"
17
17
#include "migration/vmstate.h"
18
18
19
- #define GPIOS_PER_REG 32
20
- #define GPIOS_PER_SET GPIOS_PER_REG
21
- #define GPIO_PIN_GAP_SIZE 4
22
19
#define GPIOS_PER_GROUP 8
23
- #define GPIO_GROUP_SHIFT 3
24
20
25
21
/* GPIO Source Types */
26
22
#define ASPEED_CMD_SRC_MASK 0x01010101
@@ -259,7 +255,7 @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
259
255
260
256
diff = old ^ new ;
261
257
if (diff ) {
262
- for (gpio = 0 ; gpio < GPIOS_PER_REG ; gpio ++ ) {
258
+ for (gpio = 0 ; gpio < ASPEED_GPIOS_PER_SET ; gpio ++ ) {
263
259
uint32_t mask = 1 << gpio ;
264
260
265
261
/* If the gpio needs to be updated... */
@@ -283,8 +279,7 @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
283
279
if (direction & mask ) {
284
280
/* ...trigger the line-state IRQ */
285
281
ptrdiff_t set = aspeed_gpio_set_idx (s , regs );
286
- size_t offset = set * GPIOS_PER_SET + gpio ;
287
- qemu_set_irq (s -> gpios [offset ], !!(new & mask ));
282
+ qemu_set_irq (s -> gpios [set ][gpio ], !!(new & mask ));
288
283
} else {
289
284
/* ...otherwise if we meet the line's current IRQ policy... */
290
285
if (aspeed_evaluate_irq (regs , old & mask , gpio )) {
@@ -297,21 +292,6 @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
297
292
qemu_set_irq (s -> irq , !!(s -> pending ));
298
293
}
299
294
300
- static uint32_t aspeed_adjust_pin (AspeedGPIOState * s , uint32_t pin )
301
- {
302
- AspeedGPIOClass * agc = ASPEED_GPIO_GET_CLASS (s );
303
- /*
304
- * The 2500 has a 4 pin gap in group AB and the 2400 has a 4 pin
305
- * gap in group Y (and only four pins in AB but this is the last group so
306
- * it doesn't matter).
307
- */
308
- if (agc -> gap && pin >= agc -> gap ) {
309
- pin += GPIO_PIN_GAP_SIZE ;
310
- }
311
-
312
- return pin ;
313
- }
314
-
315
295
static bool aspeed_gpio_get_pin_level (AspeedGPIOState * s , uint32_t set_idx ,
316
296
uint32_t pin )
317
297
{
@@ -367,7 +347,7 @@ static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
367
347
uint32_t new_value = 0 ;
368
348
369
349
/* for each group in set */
370
- for (i = 0 ; i < GPIOS_PER_REG ; i += GPIOS_PER_GROUP ) {
350
+ for (i = 0 ; i < ASPEED_GPIOS_PER_SET ; i += GPIOS_PER_GROUP ) {
371
351
cmd_source = extract32 (regs -> cmd_source_0 , i , 1 )
372
352
| (extract32 (regs -> cmd_source_1 , i , 1 ) << 1 );
373
353
@@ -637,7 +617,7 @@ static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
637
617
* bidirectional | 1 | 1 | data
638
618
* input only | 1 | 0 | 0
639
619
* output only | 0 | 1 | 1
640
- * no pin / gap | 0 | 0 | 0
620
+ * no pin | 0 | 0 | 0
641
621
*
642
622
* which is captured by:
643
623
* data = ( data | ~input) & output;
@@ -779,7 +759,7 @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
779
759
}
780
760
781
761
/****************** Setup functions ******************/
782
- static const GPIOSetProperties ast2400_set_props [] = {
762
+ static const GPIOSetProperties ast2400_set_props [ASPEED_GPIO_MAX_NR_SETS ] = {
783
763
[0 ] = {0xffffffff , 0xffffffff , {"A" , "B" , "C" , "D" } },
784
764
[1 ] = {0xffffffff , 0xffffffff , {"E" , "F" , "G" , "H" } },
785
765
[2 ] = {0xffffffff , 0xffffffff , {"I" , "J" , "K" , "L" } },
@@ -789,28 +769,28 @@ static const GPIOSetProperties ast2400_set_props[] = {
789
769
[6 ] = {0x0000000f , 0x0fffff0f , {"Y" , "Z" , "AA" , "AB" } },
790
770
};
791
771
792
- static const GPIOSetProperties ast2500_set_props [] = {
772
+ static const GPIOSetProperties ast2500_set_props [ASPEED_GPIO_MAX_NR_SETS ] = {
793
773
[0 ] = {0xffffffff , 0xffffffff , {"A" , "B" , "C" , "D" } },
794
774
[1 ] = {0xffffffff , 0xffffffff , {"E" , "F" , "G" , "H" } },
795
775
[2 ] = {0xffffffff , 0xffffffff , {"I" , "J" , "K" , "L" } },
796
776
[3 ] = {0xffffffff , 0xffffffff , {"M" , "N" , "O" , "P" } },
797
777
[4 ] = {0xffffffff , 0xffffffff , {"Q" , "R" , "S" , "T" } },
798
778
[5 ] = {0xffffffff , 0x0000ffff , {"U" , "V" , "W" , "X" } },
799
- [6 ] = {0xffffff0f , 0x0fffff0f , {"Y" , "Z" , "AA" , "AB" } },
779
+ [6 ] = {0x0fffffff , 0x0fffffff , {"Y" , "Z" , "AA" , "AB" } },
800
780
[7 ] = {0x000000ff , 0x000000ff , {"AC" } },
801
781
};
802
782
803
- static GPIOSetProperties ast2600_3_3v_set_props [] = {
783
+ static GPIOSetProperties ast2600_3_3v_set_props [ASPEED_GPIO_MAX_NR_SETS ] = {
804
784
[0 ] = {0xffffffff , 0xffffffff , {"A" , "B" , "C" , "D" } },
805
785
[1 ] = {0xffffffff , 0xffffffff , {"E" , "F" , "G" , "H" } },
806
786
[2 ] = {0xffffffff , 0xffffffff , {"I" , "J" , "K" , "L" } },
807
787
[3 ] = {0xffffffff , 0xffffffff , {"M" , "N" , "O" , "P" } },
808
- [4 ] = {0xffffffff , 0xffffffff , {"Q" , "R" , "S" , "T" } },
809
- [5 ] = {0xffffffff , 0x0000ffff , {"U" , "V" , "W" , "X" } },
810
- [6 ] = {0xffff0000 , 0x0fff0000 , {"Y" , "Z" , "" , " " } },
788
+ [4 ] = {0xffffffff , 0x00ffffff , {"Q" , "R" , "S" , "T" } },
789
+ [5 ] = {0xffffffff , 0xffffff00 , {"U" , "V" , "W" , "X" } },
790
+ [6 ] = {0x0000ffff , 0x0000ffff , {"Y" , "Z" } },
811
791
};
812
792
813
- static GPIOSetProperties ast2600_1_8v_set_props [] = {
793
+ static GPIOSetProperties ast2600_1_8v_set_props [ASPEED_GPIO_MAX_NR_SETS ] = {
814
794
[0 ] = {0xffffffff , 0xffffffff , {"18A" , "18B" , "18C" , "18D" } },
815
795
[1 ] = {0x0000000f , 0x0000000f , {"18E" } },
816
796
};
@@ -836,14 +816,20 @@ static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
836
816
AspeedGPIOState * s = ASPEED_GPIO (dev );
837
817
SysBusDevice * sbd = SYS_BUS_DEVICE (dev );
838
818
AspeedGPIOClass * agc = ASPEED_GPIO_GET_CLASS (s );
839
- int pin ;
840
819
841
820
/* Interrupt parent line */
842
821
sysbus_init_irq (sbd , & s -> irq );
843
822
844
823
/* Individual GPIOs */
845
- for (pin = 0 ; pin < agc -> nr_gpio_pins ; pin ++ ) {
846
- sysbus_init_irq (sbd , & s -> gpios [pin ]);
824
+ for (int i = 0 ; i < ASPEED_GPIO_MAX_NR_SETS ; i ++ ) {
825
+ const GPIOSetProperties * props = & agc -> props [i ];
826
+ uint32_t skip = ~(props -> input | props -> output );
827
+ for (int j = 0 ; j < ASPEED_GPIOS_PER_SET ; j ++ ) {
828
+ if (skip >> j & 1 ) {
829
+ continue ;
830
+ }
831
+ sysbus_init_irq (sbd , & s -> gpios [i ][j ]);
832
+ }
847
833
}
848
834
849
835
memory_region_init_io (& s -> iomem , OBJECT (s ), & aspeed_gpio_ops , s ,
@@ -856,20 +842,22 @@ static void aspeed_gpio_init(Object *obj)
856
842
{
857
843
AspeedGPIOState * s = ASPEED_GPIO (obj );
858
844
AspeedGPIOClass * agc = ASPEED_GPIO_GET_CLASS (s );
859
- int pin ;
860
-
861
- for (pin = 0 ; pin < agc -> nr_gpio_pins ; pin ++ ) {
862
- char * name ;
863
- int set_idx = pin / GPIOS_PER_SET ;
864
- int pin_idx = aspeed_adjust_pin (s , pin ) - (set_idx * GPIOS_PER_SET );
865
- int group_idx = pin_idx >> GPIO_GROUP_SHIFT ;
866
- const GPIOSetProperties * props = & agc -> props [set_idx ];
867
-
868
- name = g_strdup_printf ("gpio%s%d" , props -> group_label [group_idx ],
869
- pin_idx % GPIOS_PER_GROUP );
870
- object_property_add (obj , name , "bool" , aspeed_gpio_get_pin ,
871
- aspeed_gpio_set_pin , NULL , NULL );
872
- g_free (name );
845
+
846
+ for (int i = 0 ; i < ASPEED_GPIO_MAX_NR_SETS ; i ++ ) {
847
+ const GPIOSetProperties * props = & agc -> props [i ];
848
+ uint32_t skip = ~(props -> input | props -> output );
849
+ for (int j = 0 ; j < ASPEED_GPIOS_PER_SET ; j ++ ) {
850
+ if (skip >> j & 1 ) {
851
+ continue ;
852
+ }
853
+ int group_idx = j / GPIOS_PER_GROUP ;
854
+ int pin_idx = j % GPIOS_PER_GROUP ;
855
+ const char * group = & props -> group_label [group_idx ][0 ];
856
+ char * name = g_strdup_printf ("gpio%s%d" , group , pin_idx );
857
+ object_property_add (obj , name , "bool" , aspeed_gpio_get_pin ,
858
+ aspeed_gpio_set_pin , NULL , NULL );
859
+ g_free (name );
860
+ }
873
861
}
874
862
}
875
863
@@ -926,7 +914,6 @@ static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
926
914
agc -> props = ast2400_set_props ;
927
915
agc -> nr_gpio_pins = 216 ;
928
916
agc -> nr_gpio_sets = 7 ;
929
- agc -> gap = 196 ;
930
917
agc -> reg_table = aspeed_3_3v_gpios ;
931
918
}
932
919
@@ -937,7 +924,6 @@ static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
937
924
agc -> props = ast2500_set_props ;
938
925
agc -> nr_gpio_pins = 228 ;
939
926
agc -> nr_gpio_sets = 8 ;
940
- agc -> gap = 220 ;
941
927
agc -> reg_table = aspeed_3_3v_gpios ;
942
928
}
943
929
0 commit comments