Skip to content

Commit 402318d

Browse files
authored
Refactor LUT management in fvmap.c
Refactor GPU LUT expansion logic and ensure LUT capacity. Signed-off-by: Crecker <104427569+Creeeeger@users.noreply.github.com>
1 parent 750f9ee commit 402318d

1 file changed

Lines changed: 47 additions & 69 deletions

File tree

drivers/soc/samsung/cal-if/fvmap.c

Lines changed: 47 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,35 @@ fvmap_ratevolt_capacity(const volatile struct fvmap_header *header) {
6060
return capacity;
6161
}
6262

63+
static int vclk_ensure_lut(struct vclk *vclk, size_t need)
64+
{
65+
struct vclk_lut *new_lut;
66+
67+
if (!vclk)
68+
return -EINVAL;
69+
70+
if (vclk->lut_capacity >= need)
71+
return 0;
72+
73+
new_lut = kcalloc(need, sizeof(*new_lut), GFP_KERNEL);
74+
if (!new_lut)
75+
return -ENOMEM;
76+
77+
/* preserve existing content if any */
78+
if (vclk->lut && vclk->lut_capacity)
79+
memcpy(new_lut, vclk->lut, vclk->lut_capacity * sizeof(*new_lut));
80+
81+
/* only free if we own the old allocation */
82+
if (vclk->lut_dynamic)
83+
kfree(vclk->lut);
84+
85+
vclk->lut = new_lut;
86+
vclk->lut_capacity = need;
87+
vclk->lut_dynamic = true;
88+
89+
return 0;
90+
}
91+
6392
static size_t
6493
fvmap_calculate_initial_usage(const volatile struct fvmap_header *header,
6594
int num_of_vclks) {
@@ -84,59 +113,10 @@ fvmap_calculate_initial_usage(const volatile struct fvmap_header *header,
84113
return ALIGN(max_offset, sizeof(u32));
85114
}
86115

87-
static int fvmap_expand_gpu_lut(struct vclk *vclk, size_t manual_count) {
88-
struct vclk_lut *new_lut;
89-
size_t idx, old_count;
90-
91-
if (!vclk || !vclk->lut)
92-
return -EINVAL;
93-
94-
old_count = vclk->num_rates;
95-
if (manual_count <= old_count)
96-
return 0;
97-
98-
new_lut = kcalloc(manual_count, sizeof(*new_lut), GFP_KERNEL);
99-
if (!new_lut)
100-
return -ENOMEM;
101-
102-
for (idx = 0; idx < manual_count; idx++) {
103-
new_lut[idx].params =
104-
kcalloc(vclk->num_list, sizeof(*new_lut[idx].params), GFP_KERNEL);
105-
if (!new_lut[idx].params)
106-
goto err_free;
107-
108-
if (idx < old_count) {
109-
new_lut[idx].rate = vclk->lut[idx].rate;
110-
memcpy(new_lut[idx].params, vclk->lut[idx].params,
111-
sizeof(unsigned int) * vclk->num_list);
112-
} else if (old_count) {
113-
new_lut[idx].rate = vclk->lut[old_count - 1].rate;
114-
memcpy(new_lut[idx].params, vclk->lut[old_count - 1].params,
115-
sizeof(unsigned int) * vclk->num_list);
116-
}
117-
}
118-
119-
for (idx = 0; idx < old_count; idx++)
120-
kfree(vclk->lut[idx].params);
121-
122-
kfree(vclk->lut);
123-
124-
vclk->lut = new_lut;
125-
vclk->num_rates = manual_count;
126-
127-
return 0;
128-
129-
err_free:
130-
while (idx--)
131-
kfree(new_lut[idx].params);
132-
kfree(new_lut);
133-
134-
return -ENOMEM;
135-
}
136-
137116
static void fvmap_apply_gpu_manual_table(volatile struct fvmap_header *header,
138117
struct rate_volt_header *rate_table,
139-
struct vclk *vclk) {
118+
struct vclk *vclk)
119+
{
140120
size_t manual_count = ARRAY_SIZE(g3d_manual_ratevolt);
141121
size_t capacity = fvmap_ratevolt_capacity(header);
142122
size_t idx;
@@ -150,23 +130,26 @@ static void fvmap_apply_gpu_manual_table(volatile struct fvmap_header *header,
150130
if (!manual_count)
151131
return;
152132

133+
/* write manual rate/volt table into the FVMap */
153134
memcpy(rate_table->table, g3d_manual_ratevolt,
154135
manual_count * sizeof(struct rate_volt));
155136
header->num_of_lv = manual_count;
156137

157-
if (vclk && vclk->lut && vclk->num_rates < manual_count) {
158-
int ret = fvmap_expand_gpu_lut(vclk, manual_count);
159-
160-
if (ret) {
161-
pr_err(" G3D: failed to expand LUT to %zu entries (%d)\n",
162-
manual_count, ret);
163-
manual_count = min(manual_count, (size_t)vclk->num_rates);
164-
header->num_of_lv = manual_count;
138+
if (vclk && vclk->lut) {
139+
/* Make sure LUT storage is large enough for manual_count entries */
140+
if (vclk_ensure_lut(vclk, manual_count)) {
141+
pr_err(" G3D: failed to grow LUT to %zu entries, keeping %u\n",
142+
manual_count, vclk->lut_capacity);
143+
manual_count = min(manual_count, (size_t)vclk->lut_capacity);
165144
}
166-
}
167145

168-
if (vclk && vclk->lut) {
169-
for (idx = 0; idx < manual_count && idx < vclk->num_rates; idx++)
146+
/* clear whole LUT (your requested “clear the array”) */
147+
memset(vclk->lut, 0, vclk->lut_capacity * sizeof(*vclk->lut));
148+
149+
vclk->num_rates = manual_count;
150+
151+
/* populate LUT rates from the custom table */
152+
for (idx = 0; idx < manual_count; idx++)
170153
vclk->lut[idx].rate = g3d_manual_ratevolt[idx].rate;
171154
}
172155
}
@@ -620,12 +603,6 @@ static void fvmap_copy_from_sram(void __iomem *map_base,
620603
pr_info(" num_of_lv : %d\n", fvmap_header[i].num_of_lv);
621604
pr_info(" num_of_members : %d\n", fvmap_header[i].num_of_members);
622605

623-
if (!strcmp(vclk->name, "dvfs_g3d")) {
624-
pr_info(" G3D init level : %d\n", fvmap_header[i].init_lv);
625-
pr_info(" G3D volt_offset_percent : %d\n", volt_offset_percent);
626-
pr_info(" Using manual G3D rate/volt table\n");
627-
}
628-
629606
old = sram_base + header[i].o_ratevolt;
630607
new = map_base + fvmap_header[i].o_ratevolt;
631608

@@ -706,7 +683,8 @@ static void fvmap_copy_from_sram(void __iomem *map_base,
706683

707684
for (j = fw_lv; j < manual_lv; j++) {
708685
memcpy(&new_param->val[stride * j],
709-
&new_param->val[stride * (fw_lv - 1)], stride);
686+
&new_param->val[stride * (fw_lv - 1)],
687+
stride * sizeof(new_param->val[0]));
710688
}
711689
}
712690
}

0 commit comments

Comments
 (0)