@@ -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+
6392static size_t
6493fvmap_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-
137116static 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