|
46 | 46 | #define HSP_SM_SHRD_MBOX_FULL_INT_IE 0x04
|
47 | 47 | #define HSP_SM_SHRD_MBOX_EMPTY_INT_IE 0x08
|
48 | 48 |
|
| 49 | +#define HSP_SHRD_MBOX_TYPE1_TAG 0x40 |
| 50 | +#define HSP_SHRD_MBOX_TYPE1_DATA0 0x48 |
| 51 | +#define HSP_SHRD_MBOX_TYPE1_DATA1 0x4c |
| 52 | +#define HSP_SHRD_MBOX_TYPE1_DATA2 0x50 |
| 53 | +#define HSP_SHRD_MBOX_TYPE1_DATA3 0x54 |
| 54 | + |
49 | 55 | #define HSP_DB_CCPLEX 1
|
50 | 56 | #define HSP_DB_BPMP 3
|
51 | 57 | #define HSP_DB_MAX 7
|
52 | 58 |
|
| 59 | +#define HSP_MBOX_TYPE_MASK 0xff |
| 60 | + |
53 | 61 | struct tegra_hsp_channel;
|
54 | 62 | struct tegra_hsp;
|
55 | 63 |
|
@@ -88,6 +96,7 @@ struct tegra_hsp_db_map {
|
88 | 96 | struct tegra_hsp_soc {
|
89 | 97 | const struct tegra_hsp_db_map *map;
|
90 | 98 | bool has_per_mb_ie;
|
| 99 | + bool has_128_bit_mb; |
91 | 100 | };
|
92 | 101 |
|
93 | 102 | struct tegra_hsp {
|
@@ -396,6 +405,51 @@ static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = {
|
396 | 405 | .recv = tegra_hsp_sm_recv32,
|
397 | 406 | };
|
398 | 407 |
|
| 408 | +static void tegra_hsp_sm_send128(struct tegra_hsp_channel *channel, void *data) |
| 409 | +{ |
| 410 | + u32 value[4]; |
| 411 | + |
| 412 | + memcpy(value, data, sizeof(value)); |
| 413 | + |
| 414 | + /* Copy data */ |
| 415 | + tegra_hsp_channel_writel(channel, value[0], HSP_SHRD_MBOX_TYPE1_DATA0); |
| 416 | + tegra_hsp_channel_writel(channel, value[1], HSP_SHRD_MBOX_TYPE1_DATA1); |
| 417 | + tegra_hsp_channel_writel(channel, value[2], HSP_SHRD_MBOX_TYPE1_DATA2); |
| 418 | + tegra_hsp_channel_writel(channel, value[3], HSP_SHRD_MBOX_TYPE1_DATA3); |
| 419 | + |
| 420 | + /* Update tag to mark mailbox full */ |
| 421 | + tegra_hsp_channel_writel(channel, HSP_SM_SHRD_MBOX_FULL, |
| 422 | + HSP_SHRD_MBOX_TYPE1_TAG); |
| 423 | +} |
| 424 | + |
| 425 | +static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) |
| 426 | +{ |
| 427 | + u32 value[4]; |
| 428 | + void *msg; |
| 429 | + |
| 430 | + value[0] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA0); |
| 431 | + value[1] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA1); |
| 432 | + value[2] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA2); |
| 433 | + value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3); |
| 434 | + |
| 435 | + msg = (void *)(unsigned long)value; |
| 436 | + mbox_chan_received_data(channel->chan, msg); |
| 437 | + |
| 438 | + /* |
| 439 | + * Clear data registers and tag. |
| 440 | + */ |
| 441 | + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA0); |
| 442 | + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA1); |
| 443 | + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2); |
| 444 | + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3); |
| 445 | + tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG); |
| 446 | +} |
| 447 | + |
| 448 | +static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = { |
| 449 | + .send = tegra_hsp_sm_send128, |
| 450 | + .recv = tegra_hsp_sm_recv128, |
| 451 | +}; |
| 452 | + |
399 | 453 | static int tegra_hsp_mailbox_send_data(struct mbox_chan *chan, void *data)
|
400 | 454 | {
|
401 | 455 | struct tegra_hsp_mailbox *mb = chan->con_priv;
|
@@ -571,12 +625,20 @@ static struct mbox_chan *tegra_hsp_sm_xlate(struct mbox_controller *mbox,
|
571 | 625 |
|
572 | 626 | index = args->args[1] & TEGRA_HSP_SM_MASK;
|
573 | 627 |
|
574 |
| - if (type != TEGRA_HSP_MBOX_TYPE_SM || !hsp->shared_irqs || |
575 |
| - index >= hsp->num_sm) |
| 628 | + if ((type & HSP_MBOX_TYPE_MASK) != TEGRA_HSP_MBOX_TYPE_SM || |
| 629 | + !hsp->shared_irqs || index >= hsp->num_sm) |
576 | 630 | return ERR_PTR(-ENODEV);
|
577 | 631 |
|
578 | 632 | mb = &hsp->mailboxes[index];
|
579 |
| - mb->ops = &tegra_hsp_sm_32bit_ops; |
| 633 | + |
| 634 | + if (type & TEGRA_HSP_MBOX_TYPE_SM_128BIT) { |
| 635 | + if (!hsp->soc->has_128_bit_mb) |
| 636 | + return ERR_PTR(-ENODEV); |
| 637 | + |
| 638 | + mb->ops = &tegra_hsp_sm_128bit_ops; |
| 639 | + } else { |
| 640 | + mb->ops = &tegra_hsp_sm_32bit_ops; |
| 641 | + } |
580 | 642 |
|
581 | 643 | if ((args->args[1] & TEGRA_HSP_SM_FLAG_TX) == 0)
|
582 | 644 | mb->producer = false;
|
@@ -853,16 +915,25 @@ static const struct tegra_hsp_db_map tegra186_hsp_db_map[] = {
|
853 | 915 | static const struct tegra_hsp_soc tegra186_hsp_soc = {
|
854 | 916 | .map = tegra186_hsp_db_map,
|
855 | 917 | .has_per_mb_ie = false,
|
| 918 | + .has_128_bit_mb = false, |
856 | 919 | };
|
857 | 920 |
|
858 | 921 | static const struct tegra_hsp_soc tegra194_hsp_soc = {
|
859 | 922 | .map = tegra186_hsp_db_map,
|
860 | 923 | .has_per_mb_ie = true,
|
| 924 | + .has_128_bit_mb = false, |
| 925 | +}; |
| 926 | + |
| 927 | +static const struct tegra_hsp_soc tegra234_hsp_soc = { |
| 928 | + .map = tegra186_hsp_db_map, |
| 929 | + .has_per_mb_ie = false, |
| 930 | + .has_128_bit_mb = true, |
861 | 931 | };
|
862 | 932 |
|
863 | 933 | static const struct of_device_id tegra_hsp_match[] = {
|
864 | 934 | { .compatible = "nvidia,tegra186-hsp", .data = &tegra186_hsp_soc },
|
865 | 935 | { .compatible = "nvidia,tegra194-hsp", .data = &tegra194_hsp_soc },
|
| 936 | + { .compatible = "nvidia,tegra234-hsp", .data = &tegra234_hsp_soc }, |
866 | 937 | { }
|
867 | 938 | };
|
868 | 939 |
|
|
0 commit comments