They're now igt tests, and so if you blindly run lib/igt.cocci with spatch on tests/*c they get mangled. Move them away, but still keep them as noinst targets. Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxxx> --- tests/.gitignore | 2 - tests/Makefile.sources | 2 - tests/ddi_compute_wrpll.c | 626 --------------------------------------------- tests/skl_ddb_allocation.c | 424 ------------------------------ tools/.gitignore | 2 + tools/Makefile.sources | 5 + tools/ddi_compute_wrpll.c | 626 +++++++++++++++++++++++++++++++++++++++++++++ tools/skl_ddb_allocation.c | 424 ++++++++++++++++++++++++++++++ 8 files changed, 1057 insertions(+), 1054 deletions(-) delete mode 100644 tests/ddi_compute_wrpll.c delete mode 100644 tests/skl_ddb_allocation.c create mode 100644 tools/ddi_compute_wrpll.c create mode 100644 tools/skl_ddb_allocation.c diff --git a/tests/.gitignore b/tests/.gitignore index 3b1fb8b3d44d..b8562b62cc14 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -3,7 +3,6 @@ core_get_client_auth core_getclient core_getstats core_getversion -ddi_compute_wrpll drm_import_export drm_vma_limiter drm_vma_limiter_cached @@ -149,6 +148,5 @@ prime_nv_test prime_self_import prime_udl single-tests.txt -skl_ddb_allocation template testdisplay diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 88bb854f5d13..7724a734bed0 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -1,8 +1,6 @@ noinst_PROGRAMS = \ gem_alive \ gem_stress \ - ddi_compute_wrpll \ - skl_ddb_allocation \ $(TESTS_progs) \ $(TESTS_progs_M) \ $(HANG) \ diff --git a/tests/ddi_compute_wrpll.c b/tests/ddi_compute_wrpll.c deleted file mode 100644 index 45c28e18c4ec..000000000000 --- a/tests/ddi_compute_wrpll.c +++ /dev/null @@ -1,626 +0,0 @@ -#include <stdio.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> - -#include "intel_io.h" -#include "drmtest.h" - -#define LC_FREQ 2700 -#define LC_FREQ_2K (LC_FREQ * 2000) - -#define P_MIN 2 -#define P_MAX 64 -#define P_INC 2 - -/* Constraints for PLL good behavior */ -#define REF_MIN 48 -#define REF_MAX 400 -#define VCO_MIN 2400 -#define VCO_MAX 4800 - -#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) - -struct wrpll_rnp { - unsigned p, n2, r2; -}; - -static unsigned wrpll_get_budget_for_freq(int clock) -{ - unsigned budget; - - switch (clock) { - case 25175000: - case 25200000: - case 27000000: - case 27027000: - case 37762500: - case 37800000: - case 40500000: - case 40541000: - case 54000000: - case 54054000: - case 59341000: - case 59400000: - case 72000000: - case 74176000: - case 74250000: - case 81000000: - case 81081000: - case 89012000: - case 89100000: - case 108000000: - case 108108000: - case 111264000: - case 111375000: - case 148352000: - case 148500000: - case 162000000: - case 162162000: - case 222525000: - case 222750000: - case 296703000: - case 297000000: - budget = 0; - break; - case 233500000: - case 245250000: - case 247750000: - case 253250000: - case 298000000: - budget = 1500; - break; - case 169128000: - case 169500000: - case 179500000: - case 202000000: - budget = 2000; - break; - case 256250000: - case 262500000: - case 270000000: - case 272500000: - case 273750000: - case 280750000: - case 281250000: - case 286000000: - case 291750000: - budget = 4000; - break; - case 267250000: - case 268500000: - budget = 5000; - break; - default: - budget = 1000; - break; - } - - return budget; -} - -static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, - unsigned r2, unsigned n2, unsigned p, - struct wrpll_rnp *best) -{ - uint64_t a, b, c, d, diff, diff_best; - - /* No best (r,n,p) yet */ - if (best->p == 0) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - return; - } - - /* - * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to - * freq2k. - * - * delta = 1e6 * - * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / - * freq2k; - * - * and we would like delta <= budget. - * - * If the discrepancy is above the PPM-based budget, always prefer to - * improve upon the previous solution. However, if you're within the - * budget, try to maximize Ref * VCO, that is N / (P * R^2). - */ - a = freq2k * budget * p * r2; - b = freq2k * budget * best->p * best->r2; - diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); - diff_best = ABS_DIFF((freq2k * best->p * best->r2), - (LC_FREQ_2K * best->n2)); - c = 1000000 * diff; - d = 1000000 * diff_best; - - if (a < c && b < d) { - /* If both are above the budget, pick the closer */ - if (best->p * best->r2 * diff < p * r2 * diff_best) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - } - } else if (a >= c && b < d) { - /* If A is below the threshold but B is above it? Update. */ - best->p = p; - best->n2 = n2; - best->r2 = r2; - } else if (a >= c && b >= d) { - /* Both are below the limit, so pick the higher n2/(r2*r2) */ - if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { - best->p = p; - best->n2 = n2; - best->r2 = r2; - } - } - /* Otherwise a < c && b >= d, do nothing */ -} - -static void -wrpll_compute_rnp(int clock /* in Hz */, - unsigned *r2_out, unsigned *n2_out, unsigned *p_out) -{ - uint64_t freq2k; - unsigned p, n2, r2; - struct wrpll_rnp best = { 0, 0, 0 }; - unsigned budget; - - freq2k = clock / 100; - - budget = wrpll_get_budget_for_freq(clock); - - /* Special case handling for 540 pixel clock: bypass WR PLL entirely - * and directly pass the LC PLL to it. */ - if (freq2k == 5400000) { - *n2_out = 2; - *p_out = 1; - *r2_out = 2; - return; - } - - /* - * Ref = LC_FREQ / R, where Ref is the actual reference input seen by - * the WR PLL. - * - * We want R so that REF_MIN <= Ref <= REF_MAX. - * Injecting R2 = 2 * R gives: - * REF_MAX * r2 > LC_FREQ * 2 and - * REF_MIN * r2 < LC_FREQ * 2 - * - * Which means the desired boundaries for r2 are: - * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN - * - */ - for (r2 = LC_FREQ * 2 / REF_MAX + 1; - r2 <= LC_FREQ * 2 / REF_MIN; - r2++) { - - /* - * VCO = N * Ref, that is: VCO = N * LC_FREQ / R - * - * Once again we want VCO_MIN <= VCO <= VCO_MAX. - * Injecting R2 = 2 * R and N2 = 2 * N, we get: - * VCO_MAX * r2 > n2 * LC_FREQ and - * VCO_MIN * r2 < n2 * LC_FREQ) - * - * Which means the desired boundaries for n2 are: - * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ - */ - for (n2 = VCO_MIN * r2 / LC_FREQ + 1; - n2 <= VCO_MAX * r2 / LC_FREQ; - n2++) { - - for (p = P_MIN; p <= P_MAX; p += P_INC) - wrpll_update_rnp(freq2k, budget, - r2, n2, p, &best); - } - } - - *n2_out = best.n2; - *p_out = best.p; - *r2_out = best.r2; -} - -/* WRPLL clock dividers */ -struct wrpll_tmds_clock { - uint32_t clock; - uint16_t p; /* Post divider */ - uint16_t n2; /* Feedback divider */ - uint16_t r2; /* Reference divider */ -}; - -/* Table of matching values for WRPLL clocks programming for each frequency. - * The code assumes this table is sorted. */ -static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { - {19750000, 38, 25, 18}, - {20000000, 48, 32, 18}, - {21000000, 36, 21, 15}, - {21912000, 42, 29, 17}, - {22000000, 36, 22, 15}, - {23000000, 36, 23, 15}, - {23500000, 40, 40, 23}, - {23750000, 26, 16, 14}, - {24000000, 36, 24, 15}, - {25000000, 36, 25, 15}, - {25175000, 26, 40, 33}, - {25200000, 30, 21, 15}, - {26000000, 36, 26, 15}, - {27000000, 30, 21, 14}, - {27027000, 18, 100, 111}, - {27500000, 30, 29, 19}, - {28000000, 34, 30, 17}, - {28320000, 26, 30, 22}, - {28322000, 32, 42, 25}, - {28750000, 24, 23, 18}, - {29000000, 30, 29, 18}, - {29750000, 32, 30, 17}, - {30000000, 30, 25, 15}, - {30750000, 30, 41, 24}, - {31000000, 30, 31, 18}, - {31500000, 30, 28, 16}, - {32000000, 30, 32, 18}, - {32500000, 28, 32, 19}, - {33000000, 24, 22, 15}, - {34000000, 28, 30, 17}, - {35000000, 26, 32, 19}, - {35500000, 24, 30, 19}, - {36000000, 26, 26, 15}, - {36750000, 26, 46, 26}, - {37000000, 24, 23, 14}, - {37762500, 22, 40, 26}, - {37800000, 20, 21, 15}, - {38000000, 24, 27, 16}, - {38250000, 24, 34, 20}, - {39000000, 24, 26, 15}, - {40000000, 24, 32, 18}, - {40500000, 20, 21, 14}, - {40541000, 22, 147, 89}, - {40750000, 18, 19, 14}, - {41000000, 16, 17, 14}, - {41500000, 22, 44, 26}, - {41540000, 22, 44, 26}, - {42000000, 18, 21, 15}, - {42500000, 22, 45, 26}, - {43000000, 20, 43, 27}, - {43163000, 20, 24, 15}, - {44000000, 18, 22, 15}, - {44900000, 20, 108, 65}, - {45000000, 20, 25, 15}, - {45250000, 20, 52, 31}, - {46000000, 18, 23, 15}, - {46750000, 20, 45, 26}, - {47000000, 20, 40, 23}, - {48000000, 18, 24, 15}, - {49000000, 18, 49, 30}, - {49500000, 16, 22, 15}, - {50000000, 18, 25, 15}, - {50500000, 18, 32, 19}, - {51000000, 18, 34, 20}, - {52000000, 18, 26, 15}, - {52406000, 14, 34, 25}, - {53000000, 16, 22, 14}, - {54000000, 16, 24, 15}, - {54054000, 16, 173, 108}, - {54500000, 14, 24, 17}, - {55000000, 12, 22, 18}, - {56000000, 14, 45, 31}, - {56250000, 16, 25, 15}, - {56750000, 14, 25, 17}, - {57000000, 16, 27, 16}, - {58000000, 16, 43, 25}, - {58250000, 16, 38, 22}, - {58750000, 16, 40, 23}, - {59000000, 14, 26, 17}, - {59341000, 14, 40, 26}, - {59400000, 16, 44, 25}, - {60000000, 16, 32, 18}, - {60500000, 12, 39, 29}, - {61000000, 14, 49, 31}, - {62000000, 14, 37, 23}, - {62250000, 14, 42, 26}, - {63000000, 12, 21, 15}, - {63500000, 14, 28, 17}, - {64000000, 12, 27, 19}, - {65000000, 14, 32, 19}, - {65250000, 12, 29, 20}, - {65500000, 12, 32, 22}, - {66000000, 12, 22, 15}, - {66667000, 14, 38, 22}, - {66750000, 10, 21, 17}, - {67000000, 14, 33, 19}, - {67750000, 14, 58, 33}, - {68000000, 14, 30, 17}, - {68179000, 14, 46, 26}, - {68250000, 14, 46, 26}, - {69000000, 12, 23, 15}, - {70000000, 12, 28, 18}, - {71000000, 12, 30, 19}, - {72000000, 12, 24, 15}, - {73000000, 10, 23, 17}, - {74000000, 12, 23, 14}, - {74176000, 8, 100, 91}, - {74250000, 10, 22, 16}, - {74481000, 12, 43, 26}, - {74500000, 10, 29, 21}, - {75000000, 12, 25, 15}, - {75250000, 10, 39, 28}, - {76000000, 12, 27, 16}, - {77000000, 12, 53, 31}, - {78000000, 12, 26, 15}, - {78750000, 12, 28, 16}, - {79000000, 10, 38, 26}, - {79500000, 10, 28, 19}, - {80000000, 12, 32, 18}, - {81000000, 10, 21, 14}, - {81081000, 6, 100, 111}, - {81624000, 8, 29, 24}, - {82000000, 8, 17, 14}, - {83000000, 10, 40, 26}, - {83950000, 10, 28, 18}, - {84000000, 10, 28, 18}, - {84750000, 6, 16, 17}, - {85000000, 6, 17, 18}, - {85250000, 10, 30, 19}, - {85750000, 10, 27, 17}, - {86000000, 10, 43, 27}, - {87000000, 10, 29, 18}, - {88000000, 10, 44, 27}, - {88500000, 10, 41, 25}, - {89000000, 10, 28, 17}, - {89012000, 6, 90, 91}, - {89100000, 10, 33, 20}, - {90000000, 10, 25, 15}, - {91000000, 10, 32, 19}, - {92000000, 10, 46, 27}, - {93000000, 10, 31, 18}, - {94000000, 10, 40, 23}, - {94500000, 10, 28, 16}, - {95000000, 10, 44, 25}, - {95654000, 10, 39, 22}, - {95750000, 10, 39, 22}, - {96000000, 10, 32, 18}, - {97000000, 8, 23, 16}, - {97750000, 8, 42, 29}, - {98000000, 8, 45, 31}, - {99000000, 8, 22, 15}, - {99750000, 8, 34, 23}, - {100000000, 6, 20, 18}, - {100500000, 6, 19, 17}, - {101000000, 6, 37, 33}, - {101250000, 8, 21, 14}, - {102000000, 6, 17, 15}, - {102250000, 6, 25, 22}, - {103000000, 8, 29, 19}, - {104000000, 8, 37, 24}, - {105000000, 8, 28, 18}, - {106000000, 8, 22, 14}, - {107000000, 8, 46, 29}, - {107214000, 8, 27, 17}, - {108000000, 8, 24, 15}, - {108108000, 8, 173, 108}, - {109000000, 6, 23, 19}, - {110000000, 6, 22, 18}, - {110013000, 6, 22, 18}, - {110250000, 8, 49, 30}, - {110500000, 8, 36, 22}, - {111000000, 8, 23, 14}, - {111264000, 8, 150, 91}, - {111375000, 8, 33, 20}, - {112000000, 8, 63, 38}, - {112500000, 8, 25, 15}, - {113100000, 8, 57, 34}, - {113309000, 8, 42, 25}, - {114000000, 8, 27, 16}, - {115000000, 6, 23, 18}, - {116000000, 8, 43, 25}, - {117000000, 8, 26, 15}, - {117500000, 8, 40, 23}, - {118000000, 6, 38, 29}, - {119000000, 8, 30, 17}, - {119500000, 8, 46, 26}, - {119651000, 8, 39, 22}, - {120000000, 8, 32, 18}, - {121000000, 6, 39, 29}, - {121250000, 6, 31, 23}, - {121750000, 6, 23, 17}, - {122000000, 6, 42, 31}, - {122614000, 6, 30, 22}, - {123000000, 6, 41, 30}, - {123379000, 6, 37, 27}, - {124000000, 6, 51, 37}, - {125000000, 6, 25, 18}, - {125250000, 4, 13, 14}, - {125750000, 4, 27, 29}, - {126000000, 6, 21, 15}, - {127000000, 6, 24, 17}, - {127250000, 6, 41, 29}, - {128000000, 6, 27, 19}, - {129000000, 6, 43, 30}, - {129859000, 4, 25, 26}, - {130000000, 6, 26, 18}, - {130250000, 6, 42, 29}, - {131000000, 6, 32, 22}, - {131500000, 6, 38, 26}, - {131850000, 6, 41, 28}, - {132000000, 6, 22, 15}, - {132750000, 6, 28, 19}, - {133000000, 6, 34, 23}, - {133330000, 6, 37, 25}, - {134000000, 6, 61, 41}, - {135000000, 6, 21, 14}, - {135250000, 6, 167, 111}, - {136000000, 6, 62, 41}, - {137000000, 6, 35, 23}, - {138000000, 6, 23, 15}, - {138500000, 6, 40, 26}, - {138750000, 6, 37, 24}, - {139000000, 6, 34, 22}, - {139050000, 6, 34, 22}, - {139054000, 6, 34, 22}, - {140000000, 6, 28, 18}, - {141000000, 6, 36, 23}, - {141500000, 6, 22, 14}, - {142000000, 6, 30, 19}, - {143000000, 6, 27, 17}, - {143472000, 4, 17, 16}, - {144000000, 6, 24, 15}, - {145000000, 6, 29, 18}, - {146000000, 6, 47, 29}, - {146250000, 6, 26, 16}, - {147000000, 6, 49, 30}, - {147891000, 6, 23, 14}, - {148000000, 6, 23, 14}, - {148250000, 6, 28, 17}, - {148352000, 4, 100, 91}, - {148500000, 6, 33, 20}, - {149000000, 6, 48, 29}, - {150000000, 6, 25, 15}, - {151000000, 4, 19, 17}, - {152000000, 6, 27, 16}, - {152280000, 6, 44, 26}, - {153000000, 6, 34, 20}, - {154000000, 6, 53, 31}, - {155000000, 6, 31, 18}, - {155250000, 6, 50, 29}, - {155750000, 6, 45, 26}, - {156000000, 6, 26, 15}, - {157000000, 6, 61, 35}, - {157500000, 6, 28, 16}, - {158000000, 6, 65, 37}, - {158250000, 6, 44, 25}, - {159000000, 6, 53, 30}, - {159500000, 6, 39, 22}, - {160000000, 6, 32, 18}, - {161000000, 4, 31, 26}, - {162000000, 4, 18, 15}, - {162162000, 4, 131, 109}, - {162500000, 4, 53, 44}, - {163000000, 4, 29, 24}, - {164000000, 4, 17, 14}, - {165000000, 4, 22, 18}, - {166000000, 4, 32, 26}, - {167000000, 4, 26, 21}, - {168000000, 4, 46, 37}, - {169000000, 4, 104, 83}, - {169128000, 4, 64, 51}, - {169500000, 4, 39, 31}, - {170000000, 4, 34, 27}, - {171000000, 4, 19, 15}, - {172000000, 4, 51, 40}, - {172750000, 4, 32, 25}, - {172800000, 4, 32, 25}, - {173000000, 4, 41, 32}, - {174000000, 4, 49, 38}, - {174787000, 4, 22, 17}, - {175000000, 4, 35, 27}, - {176000000, 4, 30, 23}, - {177000000, 4, 38, 29}, - {178000000, 4, 29, 22}, - {178500000, 4, 37, 28}, - {179000000, 4, 53, 40}, - {179500000, 4, 73, 55}, - {180000000, 4, 20, 15}, - {181000000, 4, 55, 41}, - {182000000, 4, 31, 23}, - {183000000, 4, 42, 31}, - {184000000, 4, 30, 22}, - {184750000, 4, 26, 19}, - {185000000, 4, 37, 27}, - {186000000, 4, 51, 37}, - {187000000, 4, 36, 26}, - {188000000, 4, 32, 23}, - {189000000, 4, 21, 15}, - {190000000, 4, 38, 27}, - {190960000, 4, 41, 29}, - {191000000, 4, 41, 29}, - {192000000, 4, 27, 19}, - {192250000, 4, 37, 26}, - {193000000, 4, 20, 14}, - {193250000, 4, 53, 37}, - {194000000, 4, 23, 16}, - {194208000, 4, 23, 16}, - {195000000, 4, 26, 18}, - {196000000, 4, 45, 31}, - {197000000, 4, 35, 24}, - {197750000, 4, 41, 28}, - {198000000, 4, 22, 15}, - {198500000, 4, 25, 17}, - {199000000, 4, 28, 19}, - {200000000, 4, 37, 25}, - {201000000, 4, 61, 41}, - {202000000, 4, 112, 75}, - {202500000, 4, 21, 14}, - {203000000, 4, 146, 97}, - {204000000, 4, 62, 41}, - {204750000, 4, 44, 29}, - {205000000, 4, 38, 25}, - {206000000, 4, 29, 19}, - {207000000, 4, 23, 15}, - {207500000, 4, 40, 26}, - {208000000, 4, 37, 24}, - {208900000, 4, 48, 31}, - {209000000, 4, 48, 31}, - {209250000, 4, 31, 20}, - {210000000, 4, 28, 18}, - {211000000, 4, 25, 16}, - {212000000, 4, 22, 14}, - {213000000, 4, 30, 19}, - {213750000, 4, 38, 24}, - {214000000, 4, 46, 29}, - {214750000, 4, 35, 22}, - {215000000, 4, 43, 27}, - {216000000, 4, 24, 15}, - {217000000, 4, 37, 23}, - {218000000, 4, 42, 26}, - {218250000, 4, 42, 26}, - {218750000, 4, 34, 21}, - {219000000, 4, 47, 29}, - {220000000, 4, 44, 27}, - {220640000, 4, 49, 30}, - {220750000, 4, 36, 22}, - {221000000, 4, 36, 22}, - {222000000, 4, 23, 14}, - {222525000, 4, 150, 91}, - {222750000, 4, 33, 20}, - {227000000, 4, 37, 22}, - {230250000, 4, 29, 17}, - {233500000, 4, 38, 22}, - {235000000, 4, 40, 23}, - {238000000, 4, 30, 17}, - {241500000, 2, 17, 19}, - {245250000, 2, 20, 22}, - {247750000, 2, 22, 24}, - {253250000, 2, 15, 16}, - {256250000, 2, 18, 19}, - {262500000, 2, 31, 32}, - {267250000, 2, 66, 67}, - {268500000, 2, 94, 95}, - {270000000, 2, 14, 14}, - {272500000, 2, 77, 76}, - {273750000, 2, 57, 56}, - {280750000, 2, 24, 23}, - {281250000, 2, 23, 22}, - {286000000, 2, 17, 16}, - {291750000, 2, 26, 24}, - {296703000, 2, 100, 91}, - {297000000, 2, 22, 20}, - {298000000, 2, 21, 19}, -}; - -int main(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) { - const struct wrpll_tmds_clock *ref = &wrpll_tmds_clock_table[i]; - unsigned r2, n2, p; - - wrpll_compute_rnp(ref->clock, &r2, &n2, &p); - igt_fail_on_f(ref->r2 != r2 || ref->n2 != n2 || ref->p != p, - "Computed value differs for %li Hz:\n"" Reference: (%u,%u,%u)\n"" Computed: (%u,%u,%u)\n", (int64_t)ref->clock * 1000, ref->r2, ref->n2, ref->p, r2, n2, p); - } - - return 0; -} diff --git a/tests/skl_ddb_allocation.c b/tests/skl_ddb_allocation.c deleted file mode 100644 index 4d8e6d185ee7..000000000000 --- a/tests/skl_ddb_allocation.c +++ /dev/null @@ -1,424 +0,0 @@ -#include <stdint.h> -#include <stdio.h> -#include <stdbool.h> -#include <stddef.h> -#include <string.h> - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define div_u64(a, b) ((a) / (b)) - -/* - * Stub a few defines/structures - */ - -#define I915_MAX_PIPES 3 -#define I915_MAX_PLANES 3 -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define for_each_pipe(p) for ((p) = 0; (p) < 3; (p)++) -#define for_each_plane(pipe, p) for ((p) = 0; (p) < 3; (p)++) - -#define for_each_crtc(dev, crtc) \ - for (int i = 0; i < 3 && (crtc = &crtcs[i].base); i++) - -#define for_each_intel_crtc(dev, intel_crtc) \ - for (int i = 0; i < 3, intel_crtc = &crtcs[i]; i++) - -enum pipe { - PIPE_A, - PIPE_B, - PIPE_C, -}; - -enum plane { - PLANE_1, - PLANE_2, - PLANE_3, -}; - -#define pipe_name(p) ((p) + 'A') - -struct drm_device { - void *dev_private; -}; - -struct drm_i915_private { - struct drm_device *dev; -}; - -struct drm_crtc { - struct drm_device *dev; - bool active; -}; - -static bool intel_crtc_active(struct drm_crtc *crtc) -{ - return crtc->active; -} - -struct intel_crtc { - struct drm_crtc base; - enum pipe pipe; -}; - -static int intel_num_planes(struct intel_crtc *crtc) -{ - return 3; -} - -struct intel_crtc crtcs[I915_MAX_PIPES]; - -#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) - -/* - * DDB code - */ - -struct intel_wm_config { - unsigned int num_pipes_active; -}; - -struct intel_plane_wm_parameters { - uint32_t horiz_pixels; - uint32_t vert_pixels; - uint8_t bytes_per_pixel; - bool enabled; - bool scaled; -}; - -struct skl_pipe_wm_parameters { - bool active; - uint32_t pipe_htotal; - uint32_t pixel_rate; /* in KHz */ - struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; - struct intel_plane_wm_parameters cursor; -}; - -struct skl_ddb_entry { - uint16_t start, end; /* in number of blocks. 'end' is exclusive */ -}; - -static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry) -{ - /* end not set, clearly no allocation here. start can be 0 though */ - if (entry->end == 0) - return 0; - - return entry->end - entry->start; -} - -static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, - const struct skl_ddb_entry *e2) -{ - if (e1->start == e2->start && e1->end == e2->end) - return true; - - return false; -} - -struct skl_ddb_allocation { - struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; - struct skl_ddb_entry cursor[I915_MAX_PIPES]; -}; - -/* - * On gen9, we need to allocate Display Data Buffer (DDB) portions to the - * different active planes. - */ - -#define SKL_DDB_SIZE 896 /* in blocks */ - -static void -skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, - struct drm_crtc *for_crtc, - const struct intel_wm_config *config, - const struct skl_pipe_wm_parameters *params, - struct skl_ddb_entry *alloc /* out */) -{ - struct drm_crtc *crtc; - unsigned int pipe_size, ddb_size; - int nth_active_pipe; - - if (!params->active) { - alloc->start = 0; - alloc->end = 0; - return; - } - - ddb_size = SKL_DDB_SIZE; - ddb_size -= 4; /* 4 blocks for bypass path allocation */ - - nth_active_pipe = 0; - for_each_crtc(dev, crtc) { - if (!intel_crtc_active(crtc)) - continue; - - if (crtc == for_crtc) - break; - - nth_active_pipe++; - } - - pipe_size = ddb_size / config->num_pipes_active; - alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active; - alloc->end = alloc->start + pipe_size; -} - -static unsigned int skl_cursor_allocation(const struct intel_wm_config *config) -{ - if (config->num_pipes_active == 1) - return 32; - - return 8; -} - -static unsigned int -skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p) -{ - return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; -} - -/* - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching - * a 8192x4096@32bpp framebuffer: - * 3 * 4096 * 8192 * 4 < 2^32 - */ -static unsigned int -skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, - const struct skl_pipe_wm_parameters *params) -{ - unsigned int total_data_rate = 0; - int plane; - - for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { - const struct intel_plane_wm_parameters *p; - - p = ¶ms->plane[plane]; - if (!p->enabled) - continue; - - total_data_rate += skl_plane_relative_data_rate(p); - } - - return total_data_rate; -} - -static void -skl_allocate_pipe_ddb(struct drm_crtc *crtc, - const struct intel_wm_config *config, - const struct skl_pipe_wm_parameters *params, - struct skl_ddb_allocation *ddb /* out */) -{ - struct drm_device *dev = crtc->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum pipe pipe = intel_crtc->pipe; - struct skl_ddb_entry alloc; - uint16_t alloc_size, start, cursor_blocks; - uint16_t minimum[I915_MAX_PLANES]; - unsigned int total_data_rate; - int plane; - - skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc); - alloc_size = skl_ddb_entry_size(&alloc); - if (alloc_size == 0) { - memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); - memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); - return; - } - - cursor_blocks = skl_cursor_allocation(config); - ddb->cursor[pipe].start = alloc.end - cursor_blocks; - ddb->cursor[pipe].end = alloc.end; - - alloc_size -= cursor_blocks; - alloc.end -= cursor_blocks; - - /* 1. Allocate the mininum required blocks for each active plane */ - for_each_plane(pipe, plane) { - const struct intel_plane_wm_parameters *p; - - p = ¶ms->plane[plane]; - if (!p->enabled) - continue; - - minimum[plane] = 8; - alloc_size -= minimum[plane]; - } - - /* - * 2. Distribute the remaining space in proportion to the amount of - * data each plane needs to fetch from memory. - * - * FIXME: we may not allocate every single block here. - */ - total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); - - start = alloc.start; - for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { - const struct intel_plane_wm_parameters *p; - unsigned int data_rate; - uint16_t plane_blocks; - - p = ¶ms->plane[plane]; - if (!p->enabled) - continue; - - data_rate = skl_plane_relative_data_rate(p); - - /* - * promote the expression to 64 bits to avoid overflowing, the - * result is < available as data_rate / total_data_rate < 1 - */ - plane_blocks = minimum[plane]; - plane_blocks += div_u64((uint64_t)alloc_size * data_rate, - total_data_rate); - - ddb->plane[pipe][plane].start = start; - ddb->plane[pipe][plane].end = start + plane_blocks; - - start += plane_blocks; - } - -} - -static void skl_ddb_check_entry(struct skl_ddb_entry *entry, int16_t *cursor) -{ - - if (skl_ddb_entry_size(entry) == 0) - return; - - /* check that ->start is the next available block */ - if (entry->start < *cursor) - printf("error: allocation overlaps previous block\n"); - else if (entry->start >= *cursor + 1) - printf("warning: allocation leaves a hole\n"); - - *cursor = entry->end; -} - -static void skl_ddb_check_last_allocation(int16_t cursor) -{ - uint16_t last_offset = SKL_DDB_SIZE - 4; - - if (cursor < last_offset) - printf("warning: %d blocks not allocated\n", - last_offset - cursor); - else if (cursor > last_offset) - printf("error: allocation greater than available space\n"); -} - -static void skl_ddb_print(struct skl_ddb_allocation *ddb) -{ - struct skl_ddb_entry *entry; - enum pipe pipe; - int plane; - int16_t cursor = 0; - - printf("%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); - - for_each_pipe(pipe) { - printf("Pipe %c\n", pipe_name(pipe)); - - for_each_plane(pipe, plane) { - entry = &ddb->plane[pipe][plane]; - - printf(" Plane%-8d%8u%8u%8u\n", plane + 1, - entry->start, entry->end, - skl_ddb_entry_size(entry)); - - skl_ddb_check_entry(entry, &cursor); - } - - entry = &ddb->cursor[pipe]; - printf(" %-13s%8u%8u%8u\n", "Cursor", entry->start, - entry->end, skl_ddb_entry_size(entry)); - - skl_ddb_check_entry(entry, &cursor); - } - - skl_ddb_check_last_allocation(cursor); -} - -static struct drm_device drm_device; -static struct drm_i915_private drm_i915_private; - -static void init_stub(void) -{ - int i; - - drm_device.dev_private = &drm_i915_private; - drm_i915_private.dev = &drm_device; - - for (i = 0; i < I915_MAX_PIPES; i++) { - crtcs[i].base.dev = &drm_device; - crtcs[i].pipe = i; - } -} - -struct wm_input { - struct intel_wm_config config; - struct skl_pipe_wm_parameters params[I915_MAX_PIPES]; -}; - -static void wm_input_reset(struct wm_input *in) -{ - memset(in, 0, sizeof(*in)); -} - -static void wm_enable_plane(struct wm_input *in, - enum pipe pipe, enum plane plane, - uint32_t width, uint32_t height, int bpp) -{ - enum pipe i; - - in->params[pipe].active = 1; - - in->config.num_pipes_active = 0; - for_each_pipe(i) - if (in->params[i].active) - in->config.num_pipes_active++; - - in->params[pipe].plane[plane].horiz_pixels = width; - in->params[pipe].plane[plane].vert_pixels = height; - in->params[pipe].plane[plane].bytes_per_pixel = bpp; - in->params[pipe].plane[plane].enabled = true; -} - -static void skl_ddb_allocate(struct wm_input *in, - struct skl_ddb_allocation *out) -{ - struct drm_crtc *crtc; - - for_each_crtc(, crtc) { - enum pipe pipe = to_intel_crtc(crtc)->pipe; - - skl_allocate_pipe_ddb(crtc, - &in->config, &in->params[pipe], out); - } -} - -int main(int argc, char **argv) -{ - struct wm_input in; - static struct skl_ddb_allocation ddb; - - init_stub(); - - wm_input_reset(&in); - wm_enable_plane(&in, PIPE_A, PLANE_1, 1280, 1024, 4); - wm_enable_plane(&in, PIPE_A, PLANE_2, 100, 100, 4); - skl_ddb_allocate(&in, &ddb); - skl_ddb_print(&ddb); - - return 0; -} diff --git a/tools/.gitignore b/tools/.gitignore index cc87bbcc22e7..fc0426f241eb 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,4 +1,5 @@ # Please keep sorted alphabetically +ddi_compute_wrpll forcewaked intel_audio_dump intel_backlight @@ -35,3 +36,4 @@ intel_reg_write intel_stepping intel_vga_read intel_vga_write +skl_ddb_allocation diff --git a/tools/Makefile.sources b/tools/Makefile.sources index 6a73fa0a8fe0..48b89db09ec2 100644 --- a/tools/Makefile.sources +++ b/tools/Makefile.sources @@ -1,3 +1,8 @@ +noinst_PROGRAMS = \ + ddi_compute_wrpll \ + skl_ddb_allocation \ + $(NULL) + bin_PROGRAMS = \ intel_audio_dump \ intel_backlight \ diff --git a/tools/ddi_compute_wrpll.c b/tools/ddi_compute_wrpll.c new file mode 100644 index 000000000000..45c28e18c4ec --- /dev/null +++ b/tools/ddi_compute_wrpll.c @@ -0,0 +1,626 @@ +#include <stdio.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include "intel_io.h" +#include "drmtest.h" + +#define LC_FREQ 2700 +#define LC_FREQ_2K (LC_FREQ * 2000) + +#define P_MIN 2 +#define P_MAX 64 +#define P_INC 2 + +/* Constraints for PLL good behavior */ +#define REF_MIN 48 +#define REF_MAX 400 +#define VCO_MIN 2400 +#define VCO_MAX 4800 + +#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) + +struct wrpll_rnp { + unsigned p, n2, r2; +}; + +static unsigned wrpll_get_budget_for_freq(int clock) +{ + unsigned budget; + + switch (clock) { + case 25175000: + case 25200000: + case 27000000: + case 27027000: + case 37762500: + case 37800000: + case 40500000: + case 40541000: + case 54000000: + case 54054000: + case 59341000: + case 59400000: + case 72000000: + case 74176000: + case 74250000: + case 81000000: + case 81081000: + case 89012000: + case 89100000: + case 108000000: + case 108108000: + case 111264000: + case 111375000: + case 148352000: + case 148500000: + case 162000000: + case 162162000: + case 222525000: + case 222750000: + case 296703000: + case 297000000: + budget = 0; + break; + case 233500000: + case 245250000: + case 247750000: + case 253250000: + case 298000000: + budget = 1500; + break; + case 169128000: + case 169500000: + case 179500000: + case 202000000: + budget = 2000; + break; + case 256250000: + case 262500000: + case 270000000: + case 272500000: + case 273750000: + case 280750000: + case 281250000: + case 286000000: + case 291750000: + budget = 4000; + break; + case 267250000: + case 268500000: + budget = 5000; + break; + default: + budget = 1000; + break; + } + + return budget; +} + +static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, + unsigned r2, unsigned n2, unsigned p, + struct wrpll_rnp *best) +{ + uint64_t a, b, c, d, diff, diff_best; + + /* No best (r,n,p) yet */ + if (best->p == 0) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + return; + } + + /* + * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to + * freq2k. + * + * delta = 1e6 * + * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / + * freq2k; + * + * and we would like delta <= budget. + * + * If the discrepancy is above the PPM-based budget, always prefer to + * improve upon the previous solution. However, if you're within the + * budget, try to maximize Ref * VCO, that is N / (P * R^2). + */ + a = freq2k * budget * p * r2; + b = freq2k * budget * best->p * best->r2; + diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); + diff_best = ABS_DIFF((freq2k * best->p * best->r2), + (LC_FREQ_2K * best->n2)); + c = 1000000 * diff; + d = 1000000 * diff_best; + + if (a < c && b < d) { + /* If both are above the budget, pick the closer */ + if (best->p * best->r2 * diff < p * r2 * diff_best) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + } + } else if (a >= c && b < d) { + /* If A is below the threshold but B is above it? Update. */ + best->p = p; + best->n2 = n2; + best->r2 = r2; + } else if (a >= c && b >= d) { + /* Both are below the limit, so pick the higher n2/(r2*r2) */ + if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { + best->p = p; + best->n2 = n2; + best->r2 = r2; + } + } + /* Otherwise a < c && b >= d, do nothing */ +} + +static void +wrpll_compute_rnp(int clock /* in Hz */, + unsigned *r2_out, unsigned *n2_out, unsigned *p_out) +{ + uint64_t freq2k; + unsigned p, n2, r2; + struct wrpll_rnp best = { 0, 0, 0 }; + unsigned budget; + + freq2k = clock / 100; + + budget = wrpll_get_budget_for_freq(clock); + + /* Special case handling for 540 pixel clock: bypass WR PLL entirely + * and directly pass the LC PLL to it. */ + if (freq2k == 5400000) { + *n2_out = 2; + *p_out = 1; + *r2_out = 2; + return; + } + + /* + * Ref = LC_FREQ / R, where Ref is the actual reference input seen by + * the WR PLL. + * + * We want R so that REF_MIN <= Ref <= REF_MAX. + * Injecting R2 = 2 * R gives: + * REF_MAX * r2 > LC_FREQ * 2 and + * REF_MIN * r2 < LC_FREQ * 2 + * + * Which means the desired boundaries for r2 are: + * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN + * + */ + for (r2 = LC_FREQ * 2 / REF_MAX + 1; + r2 <= LC_FREQ * 2 / REF_MIN; + r2++) { + + /* + * VCO = N * Ref, that is: VCO = N * LC_FREQ / R + * + * Once again we want VCO_MIN <= VCO <= VCO_MAX. + * Injecting R2 = 2 * R and N2 = 2 * N, we get: + * VCO_MAX * r2 > n2 * LC_FREQ and + * VCO_MIN * r2 < n2 * LC_FREQ) + * + * Which means the desired boundaries for n2 are: + * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ + */ + for (n2 = VCO_MIN * r2 / LC_FREQ + 1; + n2 <= VCO_MAX * r2 / LC_FREQ; + n2++) { + + for (p = P_MIN; p <= P_MAX; p += P_INC) + wrpll_update_rnp(freq2k, budget, + r2, n2, p, &best); + } + } + + *n2_out = best.n2; + *p_out = best.p; + *r2_out = best.r2; +} + +/* WRPLL clock dividers */ +struct wrpll_tmds_clock { + uint32_t clock; + uint16_t p; /* Post divider */ + uint16_t n2; /* Feedback divider */ + uint16_t r2; /* Reference divider */ +}; + +/* Table of matching values for WRPLL clocks programming for each frequency. + * The code assumes this table is sorted. */ +static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { + {19750000, 38, 25, 18}, + {20000000, 48, 32, 18}, + {21000000, 36, 21, 15}, + {21912000, 42, 29, 17}, + {22000000, 36, 22, 15}, + {23000000, 36, 23, 15}, + {23500000, 40, 40, 23}, + {23750000, 26, 16, 14}, + {24000000, 36, 24, 15}, + {25000000, 36, 25, 15}, + {25175000, 26, 40, 33}, + {25200000, 30, 21, 15}, + {26000000, 36, 26, 15}, + {27000000, 30, 21, 14}, + {27027000, 18, 100, 111}, + {27500000, 30, 29, 19}, + {28000000, 34, 30, 17}, + {28320000, 26, 30, 22}, + {28322000, 32, 42, 25}, + {28750000, 24, 23, 18}, + {29000000, 30, 29, 18}, + {29750000, 32, 30, 17}, + {30000000, 30, 25, 15}, + {30750000, 30, 41, 24}, + {31000000, 30, 31, 18}, + {31500000, 30, 28, 16}, + {32000000, 30, 32, 18}, + {32500000, 28, 32, 19}, + {33000000, 24, 22, 15}, + {34000000, 28, 30, 17}, + {35000000, 26, 32, 19}, + {35500000, 24, 30, 19}, + {36000000, 26, 26, 15}, + {36750000, 26, 46, 26}, + {37000000, 24, 23, 14}, + {37762500, 22, 40, 26}, + {37800000, 20, 21, 15}, + {38000000, 24, 27, 16}, + {38250000, 24, 34, 20}, + {39000000, 24, 26, 15}, + {40000000, 24, 32, 18}, + {40500000, 20, 21, 14}, + {40541000, 22, 147, 89}, + {40750000, 18, 19, 14}, + {41000000, 16, 17, 14}, + {41500000, 22, 44, 26}, + {41540000, 22, 44, 26}, + {42000000, 18, 21, 15}, + {42500000, 22, 45, 26}, + {43000000, 20, 43, 27}, + {43163000, 20, 24, 15}, + {44000000, 18, 22, 15}, + {44900000, 20, 108, 65}, + {45000000, 20, 25, 15}, + {45250000, 20, 52, 31}, + {46000000, 18, 23, 15}, + {46750000, 20, 45, 26}, + {47000000, 20, 40, 23}, + {48000000, 18, 24, 15}, + {49000000, 18, 49, 30}, + {49500000, 16, 22, 15}, + {50000000, 18, 25, 15}, + {50500000, 18, 32, 19}, + {51000000, 18, 34, 20}, + {52000000, 18, 26, 15}, + {52406000, 14, 34, 25}, + {53000000, 16, 22, 14}, + {54000000, 16, 24, 15}, + {54054000, 16, 173, 108}, + {54500000, 14, 24, 17}, + {55000000, 12, 22, 18}, + {56000000, 14, 45, 31}, + {56250000, 16, 25, 15}, + {56750000, 14, 25, 17}, + {57000000, 16, 27, 16}, + {58000000, 16, 43, 25}, + {58250000, 16, 38, 22}, + {58750000, 16, 40, 23}, + {59000000, 14, 26, 17}, + {59341000, 14, 40, 26}, + {59400000, 16, 44, 25}, + {60000000, 16, 32, 18}, + {60500000, 12, 39, 29}, + {61000000, 14, 49, 31}, + {62000000, 14, 37, 23}, + {62250000, 14, 42, 26}, + {63000000, 12, 21, 15}, + {63500000, 14, 28, 17}, + {64000000, 12, 27, 19}, + {65000000, 14, 32, 19}, + {65250000, 12, 29, 20}, + {65500000, 12, 32, 22}, + {66000000, 12, 22, 15}, + {66667000, 14, 38, 22}, + {66750000, 10, 21, 17}, + {67000000, 14, 33, 19}, + {67750000, 14, 58, 33}, + {68000000, 14, 30, 17}, + {68179000, 14, 46, 26}, + {68250000, 14, 46, 26}, + {69000000, 12, 23, 15}, + {70000000, 12, 28, 18}, + {71000000, 12, 30, 19}, + {72000000, 12, 24, 15}, + {73000000, 10, 23, 17}, + {74000000, 12, 23, 14}, + {74176000, 8, 100, 91}, + {74250000, 10, 22, 16}, + {74481000, 12, 43, 26}, + {74500000, 10, 29, 21}, + {75000000, 12, 25, 15}, + {75250000, 10, 39, 28}, + {76000000, 12, 27, 16}, + {77000000, 12, 53, 31}, + {78000000, 12, 26, 15}, + {78750000, 12, 28, 16}, + {79000000, 10, 38, 26}, + {79500000, 10, 28, 19}, + {80000000, 12, 32, 18}, + {81000000, 10, 21, 14}, + {81081000, 6, 100, 111}, + {81624000, 8, 29, 24}, + {82000000, 8, 17, 14}, + {83000000, 10, 40, 26}, + {83950000, 10, 28, 18}, + {84000000, 10, 28, 18}, + {84750000, 6, 16, 17}, + {85000000, 6, 17, 18}, + {85250000, 10, 30, 19}, + {85750000, 10, 27, 17}, + {86000000, 10, 43, 27}, + {87000000, 10, 29, 18}, + {88000000, 10, 44, 27}, + {88500000, 10, 41, 25}, + {89000000, 10, 28, 17}, + {89012000, 6, 90, 91}, + {89100000, 10, 33, 20}, + {90000000, 10, 25, 15}, + {91000000, 10, 32, 19}, + {92000000, 10, 46, 27}, + {93000000, 10, 31, 18}, + {94000000, 10, 40, 23}, + {94500000, 10, 28, 16}, + {95000000, 10, 44, 25}, + {95654000, 10, 39, 22}, + {95750000, 10, 39, 22}, + {96000000, 10, 32, 18}, + {97000000, 8, 23, 16}, + {97750000, 8, 42, 29}, + {98000000, 8, 45, 31}, + {99000000, 8, 22, 15}, + {99750000, 8, 34, 23}, + {100000000, 6, 20, 18}, + {100500000, 6, 19, 17}, + {101000000, 6, 37, 33}, + {101250000, 8, 21, 14}, + {102000000, 6, 17, 15}, + {102250000, 6, 25, 22}, + {103000000, 8, 29, 19}, + {104000000, 8, 37, 24}, + {105000000, 8, 28, 18}, + {106000000, 8, 22, 14}, + {107000000, 8, 46, 29}, + {107214000, 8, 27, 17}, + {108000000, 8, 24, 15}, + {108108000, 8, 173, 108}, + {109000000, 6, 23, 19}, + {110000000, 6, 22, 18}, + {110013000, 6, 22, 18}, + {110250000, 8, 49, 30}, + {110500000, 8, 36, 22}, + {111000000, 8, 23, 14}, + {111264000, 8, 150, 91}, + {111375000, 8, 33, 20}, + {112000000, 8, 63, 38}, + {112500000, 8, 25, 15}, + {113100000, 8, 57, 34}, + {113309000, 8, 42, 25}, + {114000000, 8, 27, 16}, + {115000000, 6, 23, 18}, + {116000000, 8, 43, 25}, + {117000000, 8, 26, 15}, + {117500000, 8, 40, 23}, + {118000000, 6, 38, 29}, + {119000000, 8, 30, 17}, + {119500000, 8, 46, 26}, + {119651000, 8, 39, 22}, + {120000000, 8, 32, 18}, + {121000000, 6, 39, 29}, + {121250000, 6, 31, 23}, + {121750000, 6, 23, 17}, + {122000000, 6, 42, 31}, + {122614000, 6, 30, 22}, + {123000000, 6, 41, 30}, + {123379000, 6, 37, 27}, + {124000000, 6, 51, 37}, + {125000000, 6, 25, 18}, + {125250000, 4, 13, 14}, + {125750000, 4, 27, 29}, + {126000000, 6, 21, 15}, + {127000000, 6, 24, 17}, + {127250000, 6, 41, 29}, + {128000000, 6, 27, 19}, + {129000000, 6, 43, 30}, + {129859000, 4, 25, 26}, + {130000000, 6, 26, 18}, + {130250000, 6, 42, 29}, + {131000000, 6, 32, 22}, + {131500000, 6, 38, 26}, + {131850000, 6, 41, 28}, + {132000000, 6, 22, 15}, + {132750000, 6, 28, 19}, + {133000000, 6, 34, 23}, + {133330000, 6, 37, 25}, + {134000000, 6, 61, 41}, + {135000000, 6, 21, 14}, + {135250000, 6, 167, 111}, + {136000000, 6, 62, 41}, + {137000000, 6, 35, 23}, + {138000000, 6, 23, 15}, + {138500000, 6, 40, 26}, + {138750000, 6, 37, 24}, + {139000000, 6, 34, 22}, + {139050000, 6, 34, 22}, + {139054000, 6, 34, 22}, + {140000000, 6, 28, 18}, + {141000000, 6, 36, 23}, + {141500000, 6, 22, 14}, + {142000000, 6, 30, 19}, + {143000000, 6, 27, 17}, + {143472000, 4, 17, 16}, + {144000000, 6, 24, 15}, + {145000000, 6, 29, 18}, + {146000000, 6, 47, 29}, + {146250000, 6, 26, 16}, + {147000000, 6, 49, 30}, + {147891000, 6, 23, 14}, + {148000000, 6, 23, 14}, + {148250000, 6, 28, 17}, + {148352000, 4, 100, 91}, + {148500000, 6, 33, 20}, + {149000000, 6, 48, 29}, + {150000000, 6, 25, 15}, + {151000000, 4, 19, 17}, + {152000000, 6, 27, 16}, + {152280000, 6, 44, 26}, + {153000000, 6, 34, 20}, + {154000000, 6, 53, 31}, + {155000000, 6, 31, 18}, + {155250000, 6, 50, 29}, + {155750000, 6, 45, 26}, + {156000000, 6, 26, 15}, + {157000000, 6, 61, 35}, + {157500000, 6, 28, 16}, + {158000000, 6, 65, 37}, + {158250000, 6, 44, 25}, + {159000000, 6, 53, 30}, + {159500000, 6, 39, 22}, + {160000000, 6, 32, 18}, + {161000000, 4, 31, 26}, + {162000000, 4, 18, 15}, + {162162000, 4, 131, 109}, + {162500000, 4, 53, 44}, + {163000000, 4, 29, 24}, + {164000000, 4, 17, 14}, + {165000000, 4, 22, 18}, + {166000000, 4, 32, 26}, + {167000000, 4, 26, 21}, + {168000000, 4, 46, 37}, + {169000000, 4, 104, 83}, + {169128000, 4, 64, 51}, + {169500000, 4, 39, 31}, + {170000000, 4, 34, 27}, + {171000000, 4, 19, 15}, + {172000000, 4, 51, 40}, + {172750000, 4, 32, 25}, + {172800000, 4, 32, 25}, + {173000000, 4, 41, 32}, + {174000000, 4, 49, 38}, + {174787000, 4, 22, 17}, + {175000000, 4, 35, 27}, + {176000000, 4, 30, 23}, + {177000000, 4, 38, 29}, + {178000000, 4, 29, 22}, + {178500000, 4, 37, 28}, + {179000000, 4, 53, 40}, + {179500000, 4, 73, 55}, + {180000000, 4, 20, 15}, + {181000000, 4, 55, 41}, + {182000000, 4, 31, 23}, + {183000000, 4, 42, 31}, + {184000000, 4, 30, 22}, + {184750000, 4, 26, 19}, + {185000000, 4, 37, 27}, + {186000000, 4, 51, 37}, + {187000000, 4, 36, 26}, + {188000000, 4, 32, 23}, + {189000000, 4, 21, 15}, + {190000000, 4, 38, 27}, + {190960000, 4, 41, 29}, + {191000000, 4, 41, 29}, + {192000000, 4, 27, 19}, + {192250000, 4, 37, 26}, + {193000000, 4, 20, 14}, + {193250000, 4, 53, 37}, + {194000000, 4, 23, 16}, + {194208000, 4, 23, 16}, + {195000000, 4, 26, 18}, + {196000000, 4, 45, 31}, + {197000000, 4, 35, 24}, + {197750000, 4, 41, 28}, + {198000000, 4, 22, 15}, + {198500000, 4, 25, 17}, + {199000000, 4, 28, 19}, + {200000000, 4, 37, 25}, + {201000000, 4, 61, 41}, + {202000000, 4, 112, 75}, + {202500000, 4, 21, 14}, + {203000000, 4, 146, 97}, + {204000000, 4, 62, 41}, + {204750000, 4, 44, 29}, + {205000000, 4, 38, 25}, + {206000000, 4, 29, 19}, + {207000000, 4, 23, 15}, + {207500000, 4, 40, 26}, + {208000000, 4, 37, 24}, + {208900000, 4, 48, 31}, + {209000000, 4, 48, 31}, + {209250000, 4, 31, 20}, + {210000000, 4, 28, 18}, + {211000000, 4, 25, 16}, + {212000000, 4, 22, 14}, + {213000000, 4, 30, 19}, + {213750000, 4, 38, 24}, + {214000000, 4, 46, 29}, + {214750000, 4, 35, 22}, + {215000000, 4, 43, 27}, + {216000000, 4, 24, 15}, + {217000000, 4, 37, 23}, + {218000000, 4, 42, 26}, + {218250000, 4, 42, 26}, + {218750000, 4, 34, 21}, + {219000000, 4, 47, 29}, + {220000000, 4, 44, 27}, + {220640000, 4, 49, 30}, + {220750000, 4, 36, 22}, + {221000000, 4, 36, 22}, + {222000000, 4, 23, 14}, + {222525000, 4, 150, 91}, + {222750000, 4, 33, 20}, + {227000000, 4, 37, 22}, + {230250000, 4, 29, 17}, + {233500000, 4, 38, 22}, + {235000000, 4, 40, 23}, + {238000000, 4, 30, 17}, + {241500000, 2, 17, 19}, + {245250000, 2, 20, 22}, + {247750000, 2, 22, 24}, + {253250000, 2, 15, 16}, + {256250000, 2, 18, 19}, + {262500000, 2, 31, 32}, + {267250000, 2, 66, 67}, + {268500000, 2, 94, 95}, + {270000000, 2, 14, 14}, + {272500000, 2, 77, 76}, + {273750000, 2, 57, 56}, + {280750000, 2, 24, 23}, + {281250000, 2, 23, 22}, + {286000000, 2, 17, 16}, + {291750000, 2, 26, 24}, + {296703000, 2, 100, 91}, + {297000000, 2, 22, 20}, + {298000000, 2, 21, 19}, +}; + +int main(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) { + const struct wrpll_tmds_clock *ref = &wrpll_tmds_clock_table[i]; + unsigned r2, n2, p; + + wrpll_compute_rnp(ref->clock, &r2, &n2, &p); + igt_fail_on_f(ref->r2 != r2 || ref->n2 != n2 || ref->p != p, + "Computed value differs for %li Hz:\n"" Reference: (%u,%u,%u)\n"" Computed: (%u,%u,%u)\n", (int64_t)ref->clock * 1000, ref->r2, ref->n2, ref->p, r2, n2, p); + } + + return 0; +} diff --git a/tools/skl_ddb_allocation.c b/tools/skl_ddb_allocation.c new file mode 100644 index 000000000000..4d8e6d185ee7 --- /dev/null +++ b/tools/skl_ddb_allocation.c @@ -0,0 +1,424 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define div_u64(a, b) ((a) / (b)) + +/* + * Stub a few defines/structures + */ + +#define I915_MAX_PIPES 3 +#define I915_MAX_PLANES 3 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define for_each_pipe(p) for ((p) = 0; (p) < 3; (p)++) +#define for_each_plane(pipe, p) for ((p) = 0; (p) < 3; (p)++) + +#define for_each_crtc(dev, crtc) \ + for (int i = 0; i < 3 && (crtc = &crtcs[i].base); i++) + +#define for_each_intel_crtc(dev, intel_crtc) \ + for (int i = 0; i < 3, intel_crtc = &crtcs[i]; i++) + +enum pipe { + PIPE_A, + PIPE_B, + PIPE_C, +}; + +enum plane { + PLANE_1, + PLANE_2, + PLANE_3, +}; + +#define pipe_name(p) ((p) + 'A') + +struct drm_device { + void *dev_private; +}; + +struct drm_i915_private { + struct drm_device *dev; +}; + +struct drm_crtc { + struct drm_device *dev; + bool active; +}; + +static bool intel_crtc_active(struct drm_crtc *crtc) +{ + return crtc->active; +} + +struct intel_crtc { + struct drm_crtc base; + enum pipe pipe; +}; + +static int intel_num_planes(struct intel_crtc *crtc) +{ + return 3; +} + +struct intel_crtc crtcs[I915_MAX_PIPES]; + +#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) + +/* + * DDB code + */ + +struct intel_wm_config { + unsigned int num_pipes_active; +}; + +struct intel_plane_wm_parameters { + uint32_t horiz_pixels; + uint32_t vert_pixels; + uint8_t bytes_per_pixel; + bool enabled; + bool scaled; +}; + +struct skl_pipe_wm_parameters { + bool active; + uint32_t pipe_htotal; + uint32_t pixel_rate; /* in KHz */ + struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; + struct intel_plane_wm_parameters cursor; +}; + +struct skl_ddb_entry { + uint16_t start, end; /* in number of blocks. 'end' is exclusive */ +}; + +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry) +{ + /* end not set, clearly no allocation here. start can be 0 though */ + if (entry->end == 0) + return 0; + + return entry->end - entry->start; +} + +static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, + const struct skl_ddb_entry *e2) +{ + if (e1->start == e2->start && e1->end == e2->end) + return true; + + return false; +} + +struct skl_ddb_allocation { + struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; + struct skl_ddb_entry cursor[I915_MAX_PIPES]; +}; + +/* + * On gen9, we need to allocate Display Data Buffer (DDB) portions to the + * different active planes. + */ + +#define SKL_DDB_SIZE 896 /* in blocks */ + +static void +skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, + struct drm_crtc *for_crtc, + const struct intel_wm_config *config, + const struct skl_pipe_wm_parameters *params, + struct skl_ddb_entry *alloc /* out */) +{ + struct drm_crtc *crtc; + unsigned int pipe_size, ddb_size; + int nth_active_pipe; + + if (!params->active) { + alloc->start = 0; + alloc->end = 0; + return; + } + + ddb_size = SKL_DDB_SIZE; + ddb_size -= 4; /* 4 blocks for bypass path allocation */ + + nth_active_pipe = 0; + for_each_crtc(dev, crtc) { + if (!intel_crtc_active(crtc)) + continue; + + if (crtc == for_crtc) + break; + + nth_active_pipe++; + } + + pipe_size = ddb_size / config->num_pipes_active; + alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active; + alloc->end = alloc->start + pipe_size; +} + +static unsigned int skl_cursor_allocation(const struct intel_wm_config *config) +{ + if (config->num_pipes_active == 1) + return 32; + + return 8; +} + +static unsigned int +skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p) +{ + return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; +} + +/* + * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching + * a 8192x4096@32bpp framebuffer: + * 3 * 4096 * 8192 * 4 < 2^32 + */ +static unsigned int +skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, + const struct skl_pipe_wm_parameters *params) +{ + unsigned int total_data_rate = 0; + int plane; + + for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { + const struct intel_plane_wm_parameters *p; + + p = ¶ms->plane[plane]; + if (!p->enabled) + continue; + + total_data_rate += skl_plane_relative_data_rate(p); + } + + return total_data_rate; +} + +static void +skl_allocate_pipe_ddb(struct drm_crtc *crtc, + const struct intel_wm_config *config, + const struct skl_pipe_wm_parameters *params, + struct skl_ddb_allocation *ddb /* out */) +{ + struct drm_device *dev = crtc->dev; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct skl_ddb_entry alloc; + uint16_t alloc_size, start, cursor_blocks; + uint16_t minimum[I915_MAX_PLANES]; + unsigned int total_data_rate; + int plane; + + skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc); + alloc_size = skl_ddb_entry_size(&alloc); + if (alloc_size == 0) { + memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); + memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); + return; + } + + cursor_blocks = skl_cursor_allocation(config); + ddb->cursor[pipe].start = alloc.end - cursor_blocks; + ddb->cursor[pipe].end = alloc.end; + + alloc_size -= cursor_blocks; + alloc.end -= cursor_blocks; + + /* 1. Allocate the mininum required blocks for each active plane */ + for_each_plane(pipe, plane) { + const struct intel_plane_wm_parameters *p; + + p = ¶ms->plane[plane]; + if (!p->enabled) + continue; + + minimum[plane] = 8; + alloc_size -= minimum[plane]; + } + + /* + * 2. Distribute the remaining space in proportion to the amount of + * data each plane needs to fetch from memory. + * + * FIXME: we may not allocate every single block here. + */ + total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); + + start = alloc.start; + for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { + const struct intel_plane_wm_parameters *p; + unsigned int data_rate; + uint16_t plane_blocks; + + p = ¶ms->plane[plane]; + if (!p->enabled) + continue; + + data_rate = skl_plane_relative_data_rate(p); + + /* + * promote the expression to 64 bits to avoid overflowing, the + * result is < available as data_rate / total_data_rate < 1 + */ + plane_blocks = minimum[plane]; + plane_blocks += div_u64((uint64_t)alloc_size * data_rate, + total_data_rate); + + ddb->plane[pipe][plane].start = start; + ddb->plane[pipe][plane].end = start + plane_blocks; + + start += plane_blocks; + } + +} + +static void skl_ddb_check_entry(struct skl_ddb_entry *entry, int16_t *cursor) +{ + + if (skl_ddb_entry_size(entry) == 0) + return; + + /* check that ->start is the next available block */ + if (entry->start < *cursor) + printf("error: allocation overlaps previous block\n"); + else if (entry->start >= *cursor + 1) + printf("warning: allocation leaves a hole\n"); + + *cursor = entry->end; +} + +static void skl_ddb_check_last_allocation(int16_t cursor) +{ + uint16_t last_offset = SKL_DDB_SIZE - 4; + + if (cursor < last_offset) + printf("warning: %d blocks not allocated\n", + last_offset - cursor); + else if (cursor > last_offset) + printf("error: allocation greater than available space\n"); +} + +static void skl_ddb_print(struct skl_ddb_allocation *ddb) +{ + struct skl_ddb_entry *entry; + enum pipe pipe; + int plane; + int16_t cursor = 0; + + printf("%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); + + for_each_pipe(pipe) { + printf("Pipe %c\n", pipe_name(pipe)); + + for_each_plane(pipe, plane) { + entry = &ddb->plane[pipe][plane]; + + printf(" Plane%-8d%8u%8u%8u\n", plane + 1, + entry->start, entry->end, + skl_ddb_entry_size(entry)); + + skl_ddb_check_entry(entry, &cursor); + } + + entry = &ddb->cursor[pipe]; + printf(" %-13s%8u%8u%8u\n", "Cursor", entry->start, + entry->end, skl_ddb_entry_size(entry)); + + skl_ddb_check_entry(entry, &cursor); + } + + skl_ddb_check_last_allocation(cursor); +} + +static struct drm_device drm_device; +static struct drm_i915_private drm_i915_private; + +static void init_stub(void) +{ + int i; + + drm_device.dev_private = &drm_i915_private; + drm_i915_private.dev = &drm_device; + + for (i = 0; i < I915_MAX_PIPES; i++) { + crtcs[i].base.dev = &drm_device; + crtcs[i].pipe = i; + } +} + +struct wm_input { + struct intel_wm_config config; + struct skl_pipe_wm_parameters params[I915_MAX_PIPES]; +}; + +static void wm_input_reset(struct wm_input *in) +{ + memset(in, 0, sizeof(*in)); +} + +static void wm_enable_plane(struct wm_input *in, + enum pipe pipe, enum plane plane, + uint32_t width, uint32_t height, int bpp) +{ + enum pipe i; + + in->params[pipe].active = 1; + + in->config.num_pipes_active = 0; + for_each_pipe(i) + if (in->params[i].active) + in->config.num_pipes_active++; + + in->params[pipe].plane[plane].horiz_pixels = width; + in->params[pipe].plane[plane].vert_pixels = height; + in->params[pipe].plane[plane].bytes_per_pixel = bpp; + in->params[pipe].plane[plane].enabled = true; +} + +static void skl_ddb_allocate(struct wm_input *in, + struct skl_ddb_allocation *out) +{ + struct drm_crtc *crtc; + + for_each_crtc(, crtc) { + enum pipe pipe = to_intel_crtc(crtc)->pipe; + + skl_allocate_pipe_ddb(crtc, + &in->config, &in->params[pipe], out); + } +} + +int main(int argc, char **argv) +{ + struct wm_input in; + static struct skl_ddb_allocation ddb; + + init_stub(); + + wm_input_reset(&in); + wm_enable_plane(&in, PIPE_A, PLANE_1, 1280, 1024, 4); + wm_enable_plane(&in, PIPE_A, PLANE_2, 100, 100, 4); + skl_ddb_allocate(&in, &ddb); + skl_ddb_print(&ddb); + + return 0; +} -- 2.1.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx