1 /* 2 * Copyright (C) 2016 NVIDIA Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/clk-provider.h> 10 #include <linux/device.h> 11 #include <linux/seq_buf.h> 12 #include <linux/slab.h> 13 14 #include <soc/tegra/bpmp.h> 15 #include <soc/tegra/bpmp-abi.h> 16 17 #define TEGRA_BPMP_DUMP_CLOCK_INFO 0 18 19 #define TEGRA_BPMP_CLK_HAS_MUX BIT(0) 20 #define TEGRA_BPMP_CLK_HAS_SET_RATE BIT(1) 21 #define TEGRA_BPMP_CLK_IS_ROOT BIT(2) 22 23 struct tegra_bpmp_clk_info { 24 unsigned int id; 25 char name[MRQ_CLK_NAME_MAXLEN]; 26 unsigned int parents[MRQ_CLK_MAX_PARENTS]; 27 unsigned int num_parents; 28 unsigned long flags; 29 }; 30 31 struct tegra_bpmp_clk { 32 struct clk_hw hw; 33 34 struct tegra_bpmp *bpmp; 35 unsigned int id; 36 37 unsigned int num_parents; 38 unsigned int *parents; 39 }; 40 41 static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw) 42 { 43 return container_of(hw, struct tegra_bpmp_clk, hw); 44 } 45 46 struct tegra_bpmp_clk_message { 47 unsigned int cmd; 48 unsigned int id; 49 50 struct { 51 const void *data; 52 size_t size; 53 } tx; 54 55 struct { 56 void *data; 57 size_t size; 58 int ret; 59 } rx; 60 }; 61 62 static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp, 63 const struct tegra_bpmp_clk_message *clk) 64 { 65 struct mrq_clk_request request; 66 struct tegra_bpmp_message msg; 67 void *req = &request; 68 int err; 69 70 memset(&request, 0, sizeof(request)); 71 request.cmd_and_id = (clk->cmd << 24) | clk->id; 72 73 /* 74 * The mrq_clk_request structure has an anonymous union at offset 4 75 * that contains all possible sub-command structures. Copy the data 76 * to that union. Ideally we'd be able to refer to it by name, but 77 * doing so would require changing the ABI header and increase the 78 * maintenance burden. 79 */ 80 memcpy(req + 4, clk->tx.data, clk->tx.size); 81 82 memset(&msg, 0, sizeof(msg)); 83 msg.mrq = MRQ_CLK; 84 msg.tx.data = &request; 85 msg.tx.size = sizeof(request); 86 msg.rx.data = clk->rx.data; 87 msg.rx.size = clk->rx.size; 88 89 err = tegra_bpmp_transfer(bpmp, &msg); 90 if (err < 0) 91 return err; 92 else if (msg.rx.ret < 0) 93 return -EINVAL; 94 95 return 0; 96 } 97 98 static int tegra_bpmp_clk_prepare(struct clk_hw *hw) 99 { 100 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 101 struct tegra_bpmp_clk_message msg; 102 103 memset(&msg, 0, sizeof(msg)); 104 msg.cmd = CMD_CLK_ENABLE; 105 msg.id = clk->id; 106 107 return tegra_bpmp_clk_transfer(clk->bpmp, &msg); 108 } 109 110 static void tegra_bpmp_clk_unprepare(struct clk_hw *hw) 111 { 112 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 113 struct tegra_bpmp_clk_message msg; 114 int err; 115 116 memset(&msg, 0, sizeof(msg)); 117 msg.cmd = CMD_CLK_DISABLE; 118 msg.id = clk->id; 119 120 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 121 if (err < 0) 122 dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n", 123 clk_hw_get_name(hw), err); 124 } 125 126 static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw) 127 { 128 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 129 struct cmd_clk_is_enabled_response response; 130 struct tegra_bpmp_clk_message msg; 131 int err; 132 133 memset(&msg, 0, sizeof(msg)); 134 msg.cmd = CMD_CLK_IS_ENABLED; 135 msg.id = clk->id; 136 msg.rx.data = &response; 137 msg.rx.size = sizeof(response); 138 139 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 140 if (err < 0) 141 return err; 142 143 return response.state; 144 } 145 146 static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw, 147 unsigned long parent_rate) 148 { 149 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 150 struct cmd_clk_get_rate_response response; 151 struct cmd_clk_get_rate_request request; 152 struct tegra_bpmp_clk_message msg; 153 int err; 154 155 memset(&msg, 0, sizeof(msg)); 156 msg.cmd = CMD_CLK_GET_RATE; 157 msg.id = clk->id; 158 msg.tx.data = &request; 159 msg.tx.size = sizeof(request); 160 msg.rx.data = &response; 161 msg.rx.size = sizeof(response); 162 163 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 164 if (err < 0) 165 return err; 166 167 return response.rate; 168 } 169 170 static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate, 171 unsigned long *parent_rate) 172 { 173 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 174 struct cmd_clk_round_rate_response response; 175 struct cmd_clk_round_rate_request request; 176 struct tegra_bpmp_clk_message msg; 177 int err; 178 179 memset(&request, 0, sizeof(request)); 180 request.rate = rate; 181 182 memset(&msg, 0, sizeof(msg)); 183 msg.cmd = CMD_CLK_ROUND_RATE; 184 msg.id = clk->id; 185 msg.tx.data = &request; 186 msg.tx.size = sizeof(request); 187 msg.rx.data = &response; 188 msg.rx.size = sizeof(response); 189 190 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 191 if (err < 0) 192 return err; 193 194 return response.rate; 195 } 196 197 static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index) 198 { 199 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 200 struct cmd_clk_set_parent_response response; 201 struct cmd_clk_set_parent_request request; 202 struct tegra_bpmp_clk_message msg; 203 int err; 204 205 memset(&request, 0, sizeof(request)); 206 request.parent_id = clk->parents[index]; 207 208 memset(&msg, 0, sizeof(msg)); 209 msg.cmd = CMD_CLK_SET_PARENT; 210 msg.id = clk->id; 211 msg.tx.data = &request; 212 msg.tx.size = sizeof(request); 213 msg.rx.data = &response; 214 msg.rx.size = sizeof(response); 215 216 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 217 if (err < 0) 218 return err; 219 220 /* XXX check parent ID in response */ 221 222 return 0; 223 } 224 225 static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw) 226 { 227 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 228 struct cmd_clk_get_parent_response response; 229 struct tegra_bpmp_clk_message msg; 230 unsigned int i; 231 int err; 232 233 memset(&msg, 0, sizeof(msg)); 234 msg.cmd = CMD_CLK_GET_PARENT; 235 msg.id = clk->id; 236 msg.rx.data = &response; 237 msg.rx.size = sizeof(response); 238 239 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); 240 if (err < 0) { 241 dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n", 242 clk_hw_get_name(hw), err); 243 return U8_MAX; 244 } 245 246 for (i = 0; i < clk->num_parents; i++) 247 if (clk->parents[i] == response.parent_id) 248 return i; 249 250 return U8_MAX; 251 } 252 253 static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate, 254 unsigned long parent_rate) 255 { 256 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw); 257 struct cmd_clk_set_rate_response response; 258 struct cmd_clk_set_rate_request request; 259 struct tegra_bpmp_clk_message msg; 260 261 memset(&request, 0, sizeof(request)); 262 request.rate = rate; 263 264 memset(&msg, 0, sizeof(msg)); 265 msg.cmd = CMD_CLK_SET_RATE; 266 msg.id = clk->id; 267 msg.tx.data = &request; 268 msg.tx.size = sizeof(request); 269 msg.rx.data = &response; 270 msg.rx.size = sizeof(response); 271 272 return tegra_bpmp_clk_transfer(clk->bpmp, &msg); 273 } 274 275 static const struct clk_ops tegra_bpmp_clk_gate_ops = { 276 .prepare = tegra_bpmp_clk_prepare, 277 .unprepare = tegra_bpmp_clk_unprepare, 278 .is_prepared = tegra_bpmp_clk_is_prepared, 279 .recalc_rate = tegra_bpmp_clk_recalc_rate, 280 }; 281 282 static const struct clk_ops tegra_bpmp_clk_mux_ops = { 283 .prepare = tegra_bpmp_clk_prepare, 284 .unprepare = tegra_bpmp_clk_unprepare, 285 .is_prepared = tegra_bpmp_clk_is_prepared, 286 .recalc_rate = tegra_bpmp_clk_recalc_rate, 287 .set_parent = tegra_bpmp_clk_set_parent, 288 .get_parent = tegra_bpmp_clk_get_parent, 289 }; 290 291 static const struct clk_ops tegra_bpmp_clk_rate_ops = { 292 .prepare = tegra_bpmp_clk_prepare, 293 .unprepare = tegra_bpmp_clk_unprepare, 294 .is_prepared = tegra_bpmp_clk_is_prepared, 295 .recalc_rate = tegra_bpmp_clk_recalc_rate, 296 .round_rate = tegra_bpmp_clk_round_rate, 297 .set_rate = tegra_bpmp_clk_set_rate, 298 }; 299 300 static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = { 301 .prepare = tegra_bpmp_clk_prepare, 302 .unprepare = tegra_bpmp_clk_unprepare, 303 .is_prepared = tegra_bpmp_clk_is_prepared, 304 .recalc_rate = tegra_bpmp_clk_recalc_rate, 305 .round_rate = tegra_bpmp_clk_round_rate, 306 .set_parent = tegra_bpmp_clk_set_parent, 307 .get_parent = tegra_bpmp_clk_get_parent, 308 .set_rate = tegra_bpmp_clk_set_rate, 309 }; 310 311 static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp) 312 { 313 struct cmd_clk_get_max_clk_id_response response; 314 struct tegra_bpmp_clk_message msg; 315 int err; 316 317 memset(&msg, 0, sizeof(msg)); 318 msg.cmd = CMD_CLK_GET_MAX_CLK_ID; 319 msg.rx.data = &response; 320 msg.rx.size = sizeof(response); 321 322 err = tegra_bpmp_clk_transfer(bpmp, &msg); 323 if (err < 0) 324 return err; 325 326 if (response.max_id > INT_MAX) 327 return -E2BIG; 328 329 return response.max_id; 330 } 331 332 static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id, 333 struct tegra_bpmp_clk_info *info) 334 { 335 struct cmd_clk_get_all_info_response response; 336 struct tegra_bpmp_clk_message msg; 337 unsigned int i; 338 int err; 339 340 memset(&msg, 0, sizeof(msg)); 341 msg.cmd = CMD_CLK_GET_ALL_INFO; 342 msg.id = id; 343 msg.rx.data = &response; 344 msg.rx.size = sizeof(response); 345 346 err = tegra_bpmp_clk_transfer(bpmp, &msg); 347 if (err < 0) 348 return err; 349 350 strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN); 351 info->num_parents = response.num_parents; 352 353 for (i = 0; i < info->num_parents; i++) 354 info->parents[i] = response.parents[i]; 355 356 info->flags = response.flags; 357 358 return 0; 359 } 360 361 static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp, 362 const char *level, 363 const struct tegra_bpmp_clk_info *info) 364 { 365 const char *prefix = ""; 366 struct seq_buf buf; 367 unsigned int i; 368 char flags[64]; 369 370 seq_buf_init(&buf, flags, sizeof(flags)); 371 372 if (info->flags) 373 seq_buf_printf(&buf, "("); 374 375 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { 376 seq_buf_printf(&buf, "%smux", prefix); 377 prefix = ", "; 378 } 379 380 if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) { 381 seq_buf_printf(&buf, "%sfixed", prefix); 382 prefix = ", "; 383 } 384 385 if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) { 386 seq_buf_printf(&buf, "%sroot", prefix); 387 prefix = ", "; 388 } 389 390 if (info->flags) 391 seq_buf_printf(&buf, ")"); 392 393 dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name); 394 dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags); 395 dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents); 396 397 for (i = 0; i < info->num_parents; i++) 398 dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]); 399 } 400 401 static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp, 402 struct tegra_bpmp_clk_info **clocksp) 403 { 404 struct tegra_bpmp_clk_info *clocks; 405 unsigned int max_id, id, count = 0; 406 unsigned int holes = 0; 407 int err; 408 409 err = tegra_bpmp_clk_get_max_id(bpmp); 410 if (err < 0) 411 return err; 412 413 max_id = err; 414 415 dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id); 416 417 clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL); 418 if (!clocks) 419 return -ENOMEM; 420 421 for (id = 0; id <= max_id; id++) { 422 struct tegra_bpmp_clk_info *info = &clocks[count]; 423 424 err = tegra_bpmp_clk_get_info(bpmp, id, info); 425 if (err < 0) 426 continue; 427 428 if (info->num_parents >= U8_MAX) { 429 dev_err(bpmp->dev, 430 "clock %u has too many parents (%u, max: %u)\n", 431 id, info->num_parents, U8_MAX); 432 continue; 433 } 434 435 /* clock not exposed by BPMP */ 436 if (info->name[0] == '\0') { 437 holes++; 438 continue; 439 } 440 441 info->id = id; 442 count++; 443 444 if (TEGRA_BPMP_DUMP_CLOCK_INFO) 445 tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info); 446 } 447 448 dev_dbg(bpmp->dev, "holes: %u\n", holes); 449 *clocksp = clocks; 450 451 return count; 452 } 453 454 static const struct tegra_bpmp_clk_info * 455 tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks, 456 unsigned int num_clocks, unsigned int id) 457 { 458 unsigned int i; 459 460 for (i = 0; i < num_clocks; i++) 461 if (clocks[i].id == id) 462 return &clocks[i]; 463 464 return NULL; 465 } 466 467 static struct tegra_bpmp_clk * 468 tegra_bpmp_clk_register(struct tegra_bpmp *bpmp, 469 const struct tegra_bpmp_clk_info *info, 470 const struct tegra_bpmp_clk_info *clocks, 471 unsigned int num_clocks) 472 { 473 struct tegra_bpmp_clk *clk; 474 struct clk_init_data init; 475 const char **parents; 476 unsigned int i; 477 int err; 478 479 clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL); 480 if (!clk) 481 return ERR_PTR(-ENOMEM); 482 483 clk->id = info->id; 484 clk->bpmp = bpmp; 485 486 clk->parents = devm_kcalloc(bpmp->dev, info->num_parents, 487 sizeof(*clk->parents), GFP_KERNEL); 488 if (!clk->parents) 489 return ERR_PTR(-ENOMEM); 490 491 clk->num_parents = info->num_parents; 492 493 /* hardware clock initialization */ 494 memset(&init, 0, sizeof(init)); 495 init.name = info->name; 496 clk->hw.init = &init; 497 498 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { 499 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) 500 init.ops = &tegra_bpmp_clk_mux_rate_ops; 501 else 502 init.ops = &tegra_bpmp_clk_mux_ops; 503 } else { 504 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) 505 init.ops = &tegra_bpmp_clk_rate_ops; 506 else 507 init.ops = &tegra_bpmp_clk_gate_ops; 508 } 509 510 init.num_parents = info->num_parents; 511 512 parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL); 513 if (!parents) 514 return ERR_PTR(-ENOMEM); 515 516 for (i = 0; i < info->num_parents; i++) { 517 const struct tegra_bpmp_clk_info *parent; 518 519 /* keep a private copy of the ID to parent index map */ 520 clk->parents[i] = info->parents[i]; 521 522 parent = tegra_bpmp_clk_find(clocks, num_clocks, 523 info->parents[i]); 524 if (!parent) { 525 dev_err(bpmp->dev, "no parent %u found for %u\n", 526 info->parents[i], info->id); 527 continue; 528 } 529 530 parents[i] = parent->name; 531 } 532 533 init.parent_names = parents; 534 535 err = devm_clk_hw_register(bpmp->dev, &clk->hw); 536 537 kfree(parents); 538 539 if (err < 0) 540 return ERR_PTR(err); 541 542 return clk; 543 } 544 545 static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp, 546 struct tegra_bpmp_clk_info *infos, 547 unsigned int count) 548 { 549 struct tegra_bpmp_clk *clk; 550 unsigned int i; 551 552 bpmp->num_clocks = count; 553 554 bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL); 555 if (!bpmp->clocks) 556 return -ENOMEM; 557 558 for (i = 0; i < count; i++) { 559 struct tegra_bpmp_clk_info *info = &infos[i]; 560 561 clk = tegra_bpmp_clk_register(bpmp, info, infos, count); 562 if (IS_ERR(clk)) { 563 dev_err(bpmp->dev, 564 "failed to register clock %u (%s): %ld\n", 565 info->id, info->name, PTR_ERR(clk)); 566 continue; 567 } 568 569 bpmp->clocks[i] = clk; 570 } 571 572 return 0; 573 } 574 575 static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp) 576 { 577 unsigned int i; 578 579 for (i = 0; i < bpmp->num_clocks; i++) 580 clk_hw_unregister(&bpmp->clocks[i]->hw); 581 } 582 583 static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec, 584 void *data) 585 { 586 unsigned int id = clkspec->args[0], i; 587 struct tegra_bpmp *bpmp = data; 588 589 for (i = 0; i < bpmp->num_clocks; i++) 590 if (bpmp->clocks[i]->id == id) 591 return &bpmp->clocks[i]->hw; 592 593 return NULL; 594 } 595 596 int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp) 597 { 598 struct tegra_bpmp_clk_info *clocks; 599 unsigned int count; 600 int err; 601 602 err = tegra_bpmp_probe_clocks(bpmp, &clocks); 603 if (err < 0) 604 return err; 605 606 count = err; 607 608 dev_dbg(bpmp->dev, "%u clocks probed\n", count); 609 610 err = tegra_bpmp_register_clocks(bpmp, clocks, count); 611 if (err < 0) 612 goto free; 613 614 err = of_clk_add_hw_provider(bpmp->dev->of_node, 615 tegra_bpmp_clk_of_xlate, 616 bpmp); 617 if (err < 0) { 618 tegra_bpmp_unregister_clocks(bpmp); 619 goto free; 620 } 621 622 free: 623 kfree(clocks); 624 return err; 625 } 626