Bench.mo: Adding overclocking frequency to output

Started by Walter Schulz, July 21, 2022, 07:52:16 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Walter Schulz

Now that we have a running build environment for D45:
I would like to see overclocking frequency in bench.mo output. Along the line "Mode: <...>, Global Draw: <...>, OC frequency: <-, 160, 192, 240 MHz>

Why: It is impossible to tell right now and this info is essential IMO!


names_are_hard

Makes sense to me.  Mode and global draw are easy I think.  OC freq I don't know how to query, I haven't worked on that code at all.  Read back register values I guess?  Or maybe there's a Canon API?  I'd need someone to show me where the OC setting code is.

theBilalFakhouri

-It can be done by reading which preset was selected in sd_uhs module + if the patch is on (we need to restart the camera after selecting a preset).

-Also we need to read registers in one case:

If the user selected 160 MHz then restarted the camera, at this time 160 MHz values would be applied the patch would be active, but if the user changed the preset to something like 192 MHz without restarting the camera, the patch would stays on with 160 MHz registers, if we just read selected preset in sd_uhs it won't be correct because it's not applied yet,

we can put variable which set its value once after applying OC depending on selected OC preset in the overclocking function, but probably relying on reading registers is better?

By reading registers we can also detect 48 MHz switch (21 MB/s drop) if the preset wasn't stable using certain SD card.

Quote from: names_are_hard on July 21, 2022, 08:24:44 PM
Or maybe there's a Canon API?

There is Canon API but only with the included clock speed settings, e.g. on 700D 0x32230 address contains selected SD preset:

16 MHz = 0x1
24 MHz = 0x2
48 MHz = 0x3
96 MHz = 0x4

We don't change this in our overclocking function (it stays 0x4), probably we can define some values for us after applying OC preset like:

160 MHz = 0x10
192 MHz = 0x11
240 MHz = 0x12

We need to make sure if 0x32230 won't change back to 0x4, and if using not defined values won't trigger some Canon code.



So, it's actually possible to implement OC frequency detection, there are many ways, best one IMO is reading from registers.




@names_are_hard

Here is official sd_uhs.c code from a1ex, it contains brute-forcing code and other stuff, you need to apply OC manually, we don't use this version in our builds.
The one which we use can be found here, basically a simplified version which support and works across all DIGIC 5 models (I still need to make some little changes to make it up to date, will do it soon).

names_are_hard

Thanks, nice summary.  I agree, nicer to read it back from the cam, to detect what is really being used, not what we think should be in use.

Is this as simple as reading back the ADTG regs, does that give us the correct info?

(I've seen some screenshots now and Mode and Global Draw are already listed, I didn't realise that)

theBilalFakhouri

Quote from: names_are_hard on July 22, 2022, 02:04:10 AM
Is this as simple as reading back the ADTG regs, does that give us the correct info?

Yes, I think it's that simple.

This works (added it in card_bench.c):

/* Detect clock speed from some SD registers, see sd_uhs.c */
int sd_frequency;
static void get_sd_clock_info()
{
int C0400614 = *(volatile uint32_t*)0xC0400614;
int C0400600 = *(volatile uint32_t*)0xC0400600;
int C0400610 = *(volatile uint32_t*)0xC0400610;

if (C0400614 == 0x1D000601 && C0400610 == 0x9)
{
sd_frequency = 48;
}

if (C0400614 == 0x1D000301 && C0400610 == 0x4)
{
sd_frequency = 96;
}

if (C0400614 == 0x1D000001 && C0400610 == 0x1)
{
sd_frequency = 160;
}

if (C0400614 == 0x1D000301 && C0400600 == 0x8 && C0400610 == 0x4)
{
sd_frequency = 192;
}

if (C0400614 == 0x1D000301 && C0400600 == 0x8 && C0400610 == 0x3)
{
sd_frequency = 240;
}

return sd_frequency;
}

static char* print_benchmark_header()
{
    bmp_printf(FONT_MONO_20, 0, 40, "ML %s, %s", build_version, build_id); // this includes camera name

get_sd_clock_info();

    static char mode[100];
    snprintf(mode, sizeof(mode),
        "Mode: %s %s, Global Draw: %s, SD frequency: %d MHz",
        get_video_mode_name(1), get_display_device_name(),
        get_global_draw() ? "ON" : "OFF", sd_frequency
    );

    bmp_printf(FONT_MONO_20, 0, 60, mode);
    return mode;
}


That would ignore sd_uhs module, it will read SD registers (before the benchmark) and print the speed based on some SD registers values, works on 700D (should work on other models).
@Devs might not be perfect, feel free to review it :P

Fixme: exclude printing SD frequency in memory (RAM) benchmarks, also exclude it from other models other than DIGIC 5.

@Walter
Here is a compiled version: bench_sd_frequency.zip (crop_rec_4k branch).

SD-frequency" border="0

-Why it was named "SD frequency" instead of "OC frequency"?
Because it will works without overclocking, it will print default frequencies too like 96 MHz on 700D, and 48 MHz on 5D3, at this case there is no overclocking, so using "SD frequency" is more accurate.

names_are_hard

Cool, nice proof of concept.  SD frequency is a better name.  I like it being part of benchmarking generally, unrelated to sd_uhs module.

We probably want to check if the reg addresses are the same for D678X, if they're not it will get a bit more complicated (either use is_camera(), or a getter function in ML, so different generations can read from different locations?).

I think naming them as the addresses is quite confusing, maybe reg_C0400614 style?  sd_frequency should probably be static, no need to make it global.  I don't see any point in making the reg reads volatile, they're only used once.

SebastianC