2 * Copyright (c) 2016, NVIDIA CORPORATION.
4 * SPDX-License-Identifier: GPL-2.0
10 #include <mailbox-uclass.h>
11 #include <dt-bindings/mailbox/tegra-hsp.h>
13 #define TEGRA_HSP_DB_REG_TRIGGER 0x0
14 #define TEGRA_HSP_DB_REG_ENABLE 0x4
15 #define TEGRA_HSP_DB_REG_RAW 0x8
16 #define TEGRA_HSP_DB_REG_PENDING 0xc
18 #define TEGRA_HSP_DB_ID_CCPLEX 1
19 #define TEGRA_HSP_DB_ID_BPMP 3
20 #define TEGRA_HSP_DB_ID_NUM 7
27 DECLARE_GLOBAL_DATA_PTR
;
29 static uint32_t *tegra_hsp_reg(struct tegra_hsp
*thsp
, uint32_t db_id
,
32 return (uint32_t *)(thsp
->regs
+ thsp
->db_base
+ (db_id
* 0x100) + reg
);
35 static uint32_t tegra_hsp_readl(struct tegra_hsp
*thsp
, uint32_t db_id
,
38 uint32_t *r
= tegra_hsp_reg(thsp
, db_id
, reg
);
42 static void tegra_hsp_writel(struct tegra_hsp
*thsp
, uint32_t val
,
43 uint32_t db_id
, uint32_t reg
)
45 uint32_t *r
= tegra_hsp_reg(thsp
, db_id
, reg
);
51 static int tegra_hsp_db_id(ulong chan_id
)
54 case TEGRA_HSP_MASTER_BPMP
:
55 return TEGRA_HSP_DB_ID_BPMP
;
57 debug("Invalid channel ID\n");
62 static int tegra_hsp_request(struct mbox_chan
*chan
)
66 debug("%s(chan=%p)\n", __func__
, chan
);
68 db_id
= tegra_hsp_db_id(chan
->id
);
70 debug("tegra_hsp_db_id() failed: %d\n", db_id
);
77 static int tegra_hsp_free(struct mbox_chan
*chan
)
79 debug("%s(chan=%p)\n", __func__
, chan
);
84 static int tegra_hsp_send(struct mbox_chan
*chan
, const void *data
)
86 struct tegra_hsp
*thsp
= dev_get_priv(chan
->dev
);
89 debug("%s(chan=%p, data=%p)\n", __func__
, chan
, data
);
91 db_id
= tegra_hsp_db_id(chan
->id
);
92 tegra_hsp_writel(thsp
, 1, db_id
, TEGRA_HSP_DB_REG_TRIGGER
);
97 static int tegra_hsp_recv(struct mbox_chan
*chan
, void *data
)
99 struct tegra_hsp
*thsp
= dev_get_priv(chan
->dev
);
100 uint32_t db_id
= TEGRA_HSP_DB_ID_CCPLEX
;
103 debug("%s(chan=%p, data=%p)\n", __func__
, chan
, data
);
105 val
= tegra_hsp_readl(thsp
, db_id
, TEGRA_HSP_DB_REG_RAW
);
106 if (!(val
& BIT(chan
->id
)))
109 tegra_hsp_writel(thsp
, BIT(chan
->id
), db_id
, TEGRA_HSP_DB_REG_RAW
);
114 static int tegra_hsp_bind(struct udevice
*dev
)
116 debug("%s(dev=%p)\n", __func__
, dev
);
121 static int tegra_hsp_probe(struct udevice
*dev
)
123 struct tegra_hsp
*thsp
= dev_get_priv(dev
);
124 int nr_sm
, nr_ss
, nr_as
;
126 debug("%s(dev=%p)\n", __func__
, dev
);
128 thsp
->regs
= dev_get_addr(dev
);
129 if (thsp
->regs
== FDT_ADDR_T_NONE
)
132 nr_sm
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
, "nvidia,num-SM",
134 nr_ss
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
, "nvidia,num-SS",
136 nr_as
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
, "nvidia,num-AS",
138 thsp
->db_base
= (1 + (nr_sm
>> 1) + nr_ss
+ nr_as
) << 16;
143 static const struct udevice_id tegra_hsp_ids
[] = {
144 { .compatible
= "nvidia,tegra186-hsp" },
148 struct mbox_ops tegra_hsp_mbox_ops
= {
149 .request
= tegra_hsp_request
,
150 .free
= tegra_hsp_free
,
151 .send
= tegra_hsp_send
,
152 .recv
= tegra_hsp_recv
,
155 U_BOOT_DRIVER(tegra_hsp
) = {
157 .id
= UCLASS_MAILBOX
,
158 .of_match
= tegra_hsp_ids
,
159 .bind
= tegra_hsp_bind
,
160 .probe
= tegra_hsp_probe
,
161 .priv_auto_alloc_size
= sizeof(struct tegra_hsp
),
162 .ops
= &tegra_hsp_mbox_ops
,