summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2016-10-12 17:53:29 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:52 -0500
commit1cf7baa7fde73ae1e3f28a115dfe7bc28bc5cc75 (patch)
tree055b303162ddef59d29a3b998b6f720a30f26f10
parentc4bb19d46e1c9121a0948fa506098cbf2f64e2a6 (diff)
nvgpu: gpu: Use pstates for MCLK range
JIRA DNVGPU-168 Change-Id: I7ac05dca745b22b411fc0aa797969b97536dd2e6 Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1239466 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/1267121 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/clk/clk_mclk.c46
-rw-r--r--drivers/gpu/nvgpu/clk/clk_mclk.h13
2 files changed, 41 insertions, 18 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_mclk.c b/drivers/gpu/nvgpu/clk/clk_mclk.c
index 6ad6c054..06ff9082 100644
--- a/drivers/gpu/nvgpu/clk/clk_mclk.c
+++ b/drivers/gpu/nvgpu/clk/clk_mclk.c
@@ -2182,12 +2182,16 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g)
2182{ 2182{
2183 struct clk_mclk_state *mclk; 2183 struct clk_mclk_state *mclk;
2184 int status; 2184 int status;
2185 struct clk_set_info *p5_info;
2186 struct clk_set_info *p0_info;
2187
2185 2188
2186 gk20a_dbg_fn(""); 2189 gk20a_dbg_fn("");
2187 2190
2188 mclk = &g->clk_pmu.clk_mclk; 2191 mclk = &g->clk_pmu.clk_mclk;
2189 2192
2190 mutex_init(&mclk->mclk_mutex); 2193 mutex_init(&mclk->mclk_lock);
2194 mutex_init(&mclk->data_lock);
2191 2195
2192 /* FBPA gain WAR */ 2196 /* FBPA gain WAR */
2193 gk20a_writel(g, fb_fbpa_fbio_iref_byte_rx_ctrl_r(), 0x22222222); 2197 gk20a_writel(g, fb_fbpa_fbio_iref_byte_rx_ctrl_r(), 0x22222222);
@@ -2202,7 +2206,23 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g)
2202 /* Load RAM pattern */ 2206 /* Load RAM pattern */
2203 mclk_memory_load_training_pattern(g); 2207 mclk_memory_load_training_pattern(g);
2204 2208
2205 mclk->vreg_buf = kzalloc((sizeof(u32) * VREG_COUNT), GFP_KERNEL); 2209 p5_info = pstate_get_clk_set_info(g,
2210 CTRL_PERF_PSTATE_P5, clkwhich_mclk);
2211 if (!p5_info)
2212 return -EINVAL;
2213
2214 p0_info = pstate_get_clk_set_info(g,
2215 CTRL_PERF_PSTATE_P0, clkwhich_mclk);
2216 if (!p0_info)
2217 return -EINVAL;
2218
2219
2220 mclk->p5_min = p5_info->min_mhz;
2221 mclk->p0_min = p0_info->min_mhz;
2222
2223
2224 mclk->vreg_buf = kcalloc(VREG_COUNT,
2225 sizeof(u32), GFP_KERNEL);
2206 if (!mclk->vreg_buf) { 2226 if (!mclk->vreg_buf) {
2207 gk20a_err(dev_from_gk20a(g), 2227 gk20a_err(dev_from_gk20a(g),
2208 "unable to allocate memory for VREG"); 2228 "unable to allocate memory for VREG");
@@ -2242,15 +2262,13 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val)
2242 2262
2243 mclk = &g->clk_pmu.clk_mclk; 2263 mclk = &g->clk_pmu.clk_mclk;
2244 2264
2245 mutex_lock(&mclk->mclk_mutex); 2265 mutex_lock(&mclk->mclk_lock);
2246 2266
2247 if (!mclk->init) 2267 if (!mclk->init)
2248 goto exit_status; 2268 goto exit_status;
2249 2269
2250 /* TODO thia should be done according to VBIOS tables */ 2270 speed = (val < mclk->p5_min) ? gk20a_mclk_low_speed :
2251 2271 (val < mclk->p0_min) ? gk20a_mclk_mid_speed :
2252 speed = (val <= MCLK_LOW_SPEED_LIMIT) ? gk20a_mclk_low_speed :
2253 (val <= MCLK_MID_SPEED_LIMIT) ? gk20a_mclk_mid_speed :
2254 gk20a_mclk_high_speed; 2272 gk20a_mclk_high_speed;
2255 2273
2256 2274
@@ -2341,7 +2359,7 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val)
2341 &seq_completion_status, 0); 2359 &seq_completion_status, 0);
2342 if (seq_completion_status != 0) { 2360 if (seq_completion_status != 0) {
2343 gk20a_err(dev_from_gk20a(g), 2361 gk20a_err(dev_from_gk20a(g),
2344 "seq_scrip update failed"); 2362 "seq_script update failed");
2345 status = -EBUSY; 2363 status = -EBUSY;
2346 goto exit_status; 2364 goto exit_status;
2347 } 2365 }
@@ -2350,6 +2368,8 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val)
2350 2368
2351#ifdef CONFIG_DEBUG_FS 2369#ifdef CONFIG_DEBUG_FS
2352 g->ops.read_ptimer(g, &t1); 2370 g->ops.read_ptimer(g, &t1);
2371
2372 mutex_lock(&mclk->data_lock);
2353 mclk->switch_num++; 2373 mclk->switch_num++;
2354 2374
2355 if (mclk->switch_num == 1) { 2375 if (mclk->switch_num == 1) {
@@ -2372,10 +2392,11 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val)
2372 mclk->switch_std += 2392 mclk->switch_std +=
2373 (curr - mclk->switch_avg) * (curr - prev_avg); 2393 (curr - mclk->switch_avg) * (curr - prev_avg);
2374 } 2394 }
2395 mutex_unlock(&mclk->data_lock);
2375#endif 2396#endif
2376exit_status: 2397exit_status:
2377 2398
2378 mutex_unlock(&mclk->mclk_mutex); 2399 mutex_unlock(&mclk->mclk_lock);
2379 return status; 2400 return status;
2380} 2401}
2381 2402
@@ -2387,6 +2408,9 @@ static int mclk_debug_speed_set(void *data, u64 val)
2387 2408
2388 mclk = &g->clk_pmu.clk_mclk; 2409 mclk = &g->clk_pmu.clk_mclk;
2389 2410
2411 /* This is problematic because it can interrupt the arbiter
2412 * and send it to sleep. we need to consider removing this
2413 */
2390 if (mclk->change) 2414 if (mclk->change)
2391 return mclk->change(g, (u16) val); 2415 return mclk->change(g, (u16) val);
2392 return 0; 2416 return 0;
@@ -2410,13 +2434,13 @@ static int mclk_switch_stats_show(struct seq_file *s, void *unused)
2410 mclk = &g->clk_pmu.clk_mclk; 2434 mclk = &g->clk_pmu.clk_mclk;
2411 2435
2412 /* Make copy of structure to reduce time with lock held */ 2436 /* Make copy of structure to reduce time with lock held */
2413 mutex_lock(&mclk->mclk_mutex); 2437 mutex_lock(&mclk->data_lock);
2414 std = mclk->switch_std; 2438 std = mclk->switch_std;
2415 avg = mclk->switch_avg; 2439 avg = mclk->switch_avg;
2416 max = mclk->switch_max; 2440 max = mclk->switch_max;
2417 min = mclk->switch_min; 2441 min = mclk->switch_min;
2418 num = mclk->switch_num; 2442 num = mclk->switch_num;
2419 mutex_unlock(&mclk->mclk_mutex); 2443 mutex_unlock(&mclk->data_lock);
2420 2444
2421 tmp = std; 2445 tmp = std;
2422 do_div(tmp, num); 2446 do_div(tmp, num);
diff --git a/drivers/gpu/nvgpu/clk/clk_mclk.h b/drivers/gpu/nvgpu/clk/clk_mclk.h
index e3e6c1ee..cb7f0de0 100644
--- a/drivers/gpu/nvgpu/clk/clk_mclk.h
+++ b/drivers/gpu/nvgpu/clk/clk_mclk.h
@@ -22,15 +22,14 @@ enum gk20a_mclk_speed {
22 gk20a_mclk_high_speed, 22 gk20a_mclk_high_speed,
23}; 23};
24 24
25#define MCLK_LOW_SPEED_LIMIT 405
26#define MCLK_MID_SPEED_LIMIT 810
27#define MCLK_HIGH_SPEED_LIMIT 3003
28
29#define DEFAULT_BOOT_MCLK_SPEED MCLK_HIGH_SPEED_LIMIT
30
31struct clk_mclk_state { 25struct clk_mclk_state {
32 enum gk20a_mclk_speed speed; 26 enum gk20a_mclk_speed speed;
33 struct mutex mclk_mutex; 27 struct mutex mclk_lock;
28 struct mutex data_lock;
29
30 u16 p5_min;
31 u16 p0_min;
32
34 void *vreg_buf; 33 void *vreg_buf;
35 bool init; 34 bool init;
36 35