qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4] hw/arm/aspeed: Add Fuji machine type


From: Peter Delevoryas
Subject: Re: [PATCH v4] hw/arm/aspeed: Add Fuji machine type
Date: Tue, 7 Sep 2021 14:05:47 +0000


> On Sep 7, 2021, at 1:59 AM, Joel Stanley <joel@jms.id.au> wrote:
> 
> On Mon, 6 Sept 2021 at 13:31, <pdel@fb.com> wrote:
>> 
>> From: Peter Delevoryas <pdel@fb.com>
>> 
>> This adds a new machine type "fuji-bmc" based on the following device tree:
>> 
>> https://github.com/torvalds/linux/blob/40cb6373b46/arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
>> 
>> Most of the i2c devices are not there, they're added here:
>> 
>> https://github.com/facebook/openbmc/blob/fb2ed12002fb/meta-facebook/meta-fuji/recipes-utils/openbmc-utils/files/setup_i2c.sh
>> 
>> I tested this by building a Fuji image from Facebook's OpenBMC repo,
>> booting, and ssh'ing from host-to-guest.
>> 
>> Signed-off-by: Peter Delevoryas <pdel@fb.com>
> 
> Reviewed-by: Joel Stanley <joel@jms.id.au>

Thanks!

> 
>> +static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
>> +{
>> +    AspeedSoCState *soc = &bmc->soc;
>> +    I2CBus *i2c[144] = {};
>> +
>> +    for (int i = 0; i < 16; i++) {
>> +        i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
>> +    }
>> +    I2CBus *i2c180 = i2c[2];
>> +    I2CBus *i2c480 = i2c[8];
>> +    I2CBus *i2c600 = i2c[11];
>> +
>> +    get_pca9548_channels(i2c180, 0x70, &i2c[16]);
> 
> Wow, this is interesting. How did you go about testing it? Are you
> sure you didn't overwrite any of the pointers?
> 
> It might be worth coming up with a better way of describing all of the
> i2c buses for future machines.
> 
> Cheers,
> 
> Joel

Ah, yes, so, I took the compiled device tree output and printed it out,
and it has a complete list of the i2c aliases from all of the component
device tree’s, like this:

dtc openbmc/build-fuji/tmp/deploy/images/fuji/aspeed-bmc-facebook-fuji.dtb

aliases {
        i2c0 = "/ahb/apb/bus@1e78a000/i2c-bus@80";
        i2c1 = "/ahb/apb/bus@1e78a000/i2c-bus@100";
        i2c2 = "/ahb/apb/bus@1e78a000/i2c-bus@180";
        i2c3 = "/ahb/apb/bus@1e78a000/i2c-bus@200";
        i2c4 = "/ahb/apb/bus@1e78a000/i2c-bus@280";
        i2c5 = "/ahb/apb/bus@1e78a000/i2c-bus@300";
        i2c6 = "/ahb/apb/bus@1e78a000/i2c-bus@380";
        i2c7 = "/ahb/apb/bus@1e78a000/i2c-bus@400";
        i2c8 = "/ahb/apb/bus@1e78a000/i2c-bus@480";
        i2c9 = "/ahb/apb/bus@1e78a000/i2c-bus@500";
        i2c10 = "/ahb/apb/bus@1e78a000/i2c-bus@580";
        i2c11 = "/ahb/apb/bus@1e78a000/i2c-bus@600";
        i2c12 = "/ahb/apb/bus@1e78a000/i2c-bus@680";
        i2c13 = "/ahb/apb/bus@1e78a000/i2c-bus@700";
        i2c14 = "/ahb/apb/bus@1e78a000/i2c-bus@780";
        i2c15 = "/ahb/apb/bus@1e78a000/i2c-bus@800";
        ...
        i2c16 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@0";
        i2c17 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@1";
        i2c18 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@2";
        i2c19 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@3";
        i2c20 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@4";
        i2c21 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@5";
        i2c22 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@6";
        i2c23 = "/ahb/apb/bus@1e78a000/i2c-bus@180/i2c-switch@70/i2c@7";
        i2c24 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@0";
        i2c25 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@1";
        i2c26 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@2";
        i2c27 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@3";
        i2c28 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@4";
        i2c29 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@5";
        i2c30 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@6";
        i2c31 = "/ahb/apb/bus@1e78a000/i2c-bus@480/i2c-switch@70/i2c@7";
        i2c40 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@0";
        i2c41 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@1";
        i2c42 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@2";
        i2c43 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@3";
        i2c44 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@4";
        i2c46 = "/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@6";
        ...
        i2c143 = 
"/ahb/apb/bus@1e78a000/i2c-bus@600/i2c-switch@77/i2c@7/i2c-switch@76/i2c@7";
};

And setup_i2c.sh’s first parameter is referencing these aliases:

# # i2c-mux 2, channel 2
i2c_device_add 17 0x4c lm75   #SCM temp. sensor
i2c_device_add 17 0x4d lm75   #SCM temp. sensor

# # i2c-mux 2, channel 3
i2c_device_add 19 0x52 24c64   #EEPROM

# # i2c-mux 2, channel 4
i2c_device_add 20 0x50 24c02   #BMC54616S EEPROM

# # i2c-mux 2, channel 6
i2c_device_add 22 0x52 24c02   #BMC54616S EEPROM

My first idea was to make some kind of tree definition
describing the i2c switches and then do a breadth first
search/etc to enumerate all of the buses.

I2CBus *i2c[144] = {}
// Initialize base set of i2c buses.
i2c[0] = …
i2c[1] = …
…
i2c[15] = …
// Initialize switch definitions, includes
// some kind of reference to its parent bus.
struct { … } switches[] = {…}
// Populate i2c buses using switch definitions.
for (int i = 0; i < sizeof(switches)/sizeof(switches[0]); i++) {
    I2CSlave *switch = find_switch(i2c, switches[i]);
                       ^^^^Recursive function or something
    for (int j = 0; j < 8; j++) {
        // Special case because fuji datasheet skips 32..40
        if (n == 32) {
            n = 40;
        }
        i2c[n++] = aspeed_i2c_get_bus(switch, j);
    }
}

I’m realizing, I probably should have done this, but I also realized
there’s not that many switches in the system, so if you just automate
the get_channels() part (x8 buses for each switch) then it was
not unreasonable to just manually write out the locations for each switch.

As far as testing: I didn’t do a lot, I mostly just eyeball’d it
more after writing it out and then I looked at the boot logs, so
I’m still not _absolutely_ sure that I got it right. Let me know
if you guys think I should refactor this!

Thanks,
Peter

> 
>> +    get_pca9548_channels(i2c480, 0x70, &i2c[24]);
>> +    /* NOTE: The device tree skips [32, 40) in the alias numbering */
>> +    get_pca9548_channels(i2c600, 0x77, &i2c[40]);
>> +    get_pca9548_channels(i2c[24], 0x71, &i2c[48]);
>> +    get_pca9548_channels(i2c[25], 0x72, &i2c[56]);
>> +    get_pca9548_channels(i2c[26], 0x76, &i2c[64]);
>> +    get_pca9548_channels(i2c[27], 0x76, &i2c[72]);
>> +    for (int i = 0; i < 8; i++) {
>> +        get_pca9548_channels(i2c[40 + i], 0x76, &i2c[80 + i * 8]);
>> +    }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]