2424#define SPRD_MBOX_IRQ_STS 0x18
2525#define SPRD_MBOX_IRQ_MSK 0x1c
2626#define SPRD_MBOX_LOCK 0x20
27- #define SPRD_MBOX_FIFO_DEPTH 0x24
27+ #define SPRD_MBOX_FIFO_DEPTH 0x24 /* outbox only */
28+ #define SPRD_MBOX_IN_FIFO_STS2 0x24 /* inbox only, revision 2 */
2829
2930/* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */
3031#define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16)
3132#define SPRD_INBOX_FIFO_OVERLOW_MASK GENMASK(15, 8)
3233#define SPRD_INBOX_FIFO_DELIVER_SHIFT 16
3334#define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0)
3435
36+ /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_RST register */
37+ #define SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST GENMASK(31, 0)
38+
39+ /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_STS register */
40+ #define SPRD_INBOX_R2_FIFO_DELIVER_MASK GENMASK(15, 0)
41+
42+ /* Bit and mask definition for SPRD_MBOX_IN_FIFO_STS2 register */
43+ #define SPRD_INBOX_R2_FIFO_OVERFLOW_MASK GENMASK(31, 16)
44+ #define SPRD_INBOX_R2_FIFO_BUSY_MASK GENMASK(15, 0)
45+
3546/* Bit and mask definition for SPRD_MBOX_IRQ_STS register */
36- #define SPRD_MBOX_IRQ_CLR BIT( 0)
47+ #define SPRD_MBOX_IRQ_CLR GENMASK(31, 0)
3748
3849/* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */
3950#define SPRD_OUTBOX_FIFO_FULL BIT(2)
5263#define SPRD_OUTBOX_FIFO_IRQ_MASK GENMASK(4, 0)
5364
5465#define SPRD_OUTBOX_BASE_SPAN 0x1000
55- #define SPRD_MBOX_CHAN_MAX 8
56- #define SPRD_SUPP_INBOX_ID_SC9863A 7
66+ #define SPRD_MBOX_R1_CHAN_MAX 8
67+ #define SPRD_MBOX_R2_CHAN_MAX 16
68+
69+ enum sprd_mbox_version {
70+ SPRD_MBOX_R1 ,
71+ SPRD_MBOX_R2 ,
72+ };
73+
74+ struct sprd_mbox_info {
75+ enum sprd_mbox_version version ;
76+ unsigned long supp_id ;
77+ };
5778
5879struct sprd_mbox_priv {
5980 struct mbox_controller mbox ;
@@ -64,9 +85,11 @@ struct sprd_mbox_priv {
6485 void __iomem * supp_base ;
6586 u32 outbox_fifo_depth ;
6687
88+ const struct sprd_mbox_info * info ;
89+
6790 struct mutex lock ;
6891 u32 refcnt ;
69- struct mbox_chan chan [SPRD_MBOX_CHAN_MAX ];
92+ struct mbox_chan chan [SPRD_MBOX_R2_CHAN_MAX ];
7093};
7194
7295static struct sprd_mbox_priv * to_sprd_mbox_priv (struct mbox_controller * mbox )
@@ -154,22 +177,34 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
154177{
155178 struct sprd_mbox_priv * priv = data ;
156179 struct mbox_chan * chan ;
157- u32 fifo_sts , send_sts , busy , id ;
180+ u32 fifo_sts , fifo_sts2 , send_sts , busy , id ;
158181
159182 fifo_sts = readl (priv -> inbox_base + SPRD_MBOX_FIFO_STS );
160183
184+ if (priv -> info -> version == SPRD_MBOX_R2 )
185+ fifo_sts2 = readl (priv -> inbox_base + SPRD_MBOX_IN_FIFO_STS2 );
186+
161187 /* Get the inbox data delivery status */
162- send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK ) >>
163- SPRD_INBOX_FIFO_DELIVER_SHIFT ;
188+ if (priv -> info -> version == SPRD_MBOX_R2 ) {
189+ send_sts = fifo_sts & SPRD_INBOX_R2_FIFO_DELIVER_MASK ;
190+ } else {
191+ send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK ) >>
192+ SPRD_INBOX_FIFO_DELIVER_SHIFT ;
193+ }
194+
164195 if (!send_sts ) {
165196 dev_warn_ratelimited (priv -> dev , "spurious inbox interrupt\n" );
166197 return IRQ_NONE ;
167198 }
168199
169200 /* Clear FIFO delivery and overflow status first */
170- writel (fifo_sts &
171- (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK ),
172- priv -> inbox_base + SPRD_MBOX_FIFO_RST );
201+ if (priv -> info -> version == SPRD_MBOX_R2 ) {
202+ writel (SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST ,
203+ priv -> inbox_base + SPRD_MBOX_FIFO_RST );
204+ } else {
205+ writel (fifo_sts & (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK ),
206+ priv -> inbox_base + SPRD_MBOX_FIFO_RST );
207+ }
173208
174209 while (send_sts ) {
175210 id = __ffs (send_sts );
@@ -181,7 +216,11 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
181216 * Check if the message was fetched by remote target, if yes,
182217 * that means the transmission has been completed.
183218 */
184- busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK ;
219+ if (priv -> info -> version == SPRD_MBOX_R2 )
220+ busy = fifo_sts2 & SPRD_INBOX_R2_FIFO_BUSY_MASK ;
221+ else
222+ busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK ;
223+
185224 if (!(busy & BIT (id )))
186225 mbox_chan_txdone (chan , 0 );
187226 }
@@ -295,7 +334,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)
295334 struct device * dev = & pdev -> dev ;
296335 struct sprd_mbox_priv * priv ;
297336 int ret , inbox_irq , outbox_irq , supp_irq ;
298- unsigned long id , supp ;
337+ unsigned long id ;
299338 struct clk * clk ;
300339
301340 priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
@@ -305,6 +344,10 @@ static int sprd_mbox_probe(struct platform_device *pdev)
305344 priv -> dev = dev ;
306345 mutex_init (& priv -> lock );
307346
347+ priv -> info = of_device_get_match_data (dev );
348+ if (!priv -> info )
349+ return - EINVAL ;
350+
308351 /*
309352 * Unisoc mailbox uses an inbox to send messages to the target
310353 * core, and uses (an) outbox(es) to receive messages from other
@@ -362,24 +405,28 @@ static int sprd_mbox_probe(struct platform_device *pdev)
362405 return ret ;
363406 }
364407
365- supp = (unsigned long ) of_device_get_match_data (dev );
366- if (!supp ) {
408+ if (!priv -> info -> supp_id ) {
367409 dev_err (dev , "no supplementary outbox specified\n" );
368410 return - ENODEV ;
369411 }
370- priv -> supp_base = priv -> outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp );
412+ priv -> supp_base = priv -> outbox_base +
413+ (SPRD_OUTBOX_BASE_SPAN * priv -> info -> supp_id );
371414 }
372415
373416 /* Get the default outbox FIFO depth */
374417 priv -> outbox_fifo_depth =
375418 readl (priv -> outbox_base + SPRD_MBOX_FIFO_DEPTH ) + 1 ;
376419 priv -> mbox .dev = dev ;
377420 priv -> mbox .chans = & priv -> chan [0 ];
378- priv -> mbox .num_chans = SPRD_MBOX_CHAN_MAX ;
379421 priv -> mbox .ops = & sprd_mbox_ops ;
380422 priv -> mbox .txdone_irq = true;
381423
382- for (id = 0 ; id < SPRD_MBOX_CHAN_MAX ; id ++ )
424+ if (priv -> info -> version == SPRD_MBOX_R2 )
425+ priv -> mbox .num_chans = SPRD_MBOX_R2_CHAN_MAX ;
426+ else
427+ priv -> mbox .num_chans = SPRD_MBOX_R1_CHAN_MAX ;
428+
429+ for (id = 0 ; id < priv -> mbox .num_chans ; id ++ )
383430 priv -> chan [id ].con_priv = (void * )id ;
384431
385432 ret = devm_mbox_controller_register (dev , & priv -> mbox );
@@ -391,10 +438,24 @@ static int sprd_mbox_probe(struct platform_device *pdev)
391438 return 0 ;
392439}
393440
441+ static const struct sprd_mbox_info sc9860_mbox_info = {
442+ .version = SPRD_MBOX_R1 ,
443+ };
444+
445+ static const struct sprd_mbox_info sc9863a_mbox_info = {
446+ .version = SPRD_MBOX_R1 ,
447+ .supp_id = 7 ,
448+ };
449+
450+ static const struct sprd_mbox_info ums9230_mbox_info = {
451+ .version = SPRD_MBOX_R2 ,
452+ .supp_id = 6 ,
453+ };
454+
394455static const struct of_device_id sprd_mbox_of_match [] = {
395- { .compatible = "sprd,sc9860-mailbox" },
396- { .compatible = "sprd,sc9863a-mailbox" ,
397- .data = ( void * ) SPRD_SUPP_INBOX_ID_SC9863A },
456+ { .compatible = "sprd,sc9860-mailbox" , . data = & sc9860_mbox_info },
457+ { .compatible = "sprd,sc9863a-mailbox" , . data = & sc9863a_mbox_info },
458+ { . compatible = "sprd,ums9230-mailbox" , .data = & ums9230_mbox_info },
398459 { },
399460};
400461MODULE_DEVICE_TABLE (of , sprd_mbox_of_match );
0 commit comments