336
[R_SLAVE_CONFIG] = 0xffffffff,
337
};
338
339
+static inline bool dw_i3c_has_hdr_ts(DWI3C *s)
340
+{
341
+ return ARRAY_FIELD_EX32(s->regs, HW_CAPABILITY, HDR_TS);
342
+}
343
+
344
+static inline bool dw_i3c_has_hdr_ddr(DWI3C *s)
345
+{
346
+ return ARRAY_FIELD_EX32(s->regs, HW_CAPABILITY, HDR_DDR);
347
+}
348
+
349
+static inline bool dw_i3c_can_transmit(DWI3C *s)
350
+{
351
+ /*
352
+ * We can only transmit if we're enabled and the resume bit is cleared.
353
+ * The resume bit is set on a transaction error, and software must clear it.
354
+ */
355
+ return ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, I3C_EN) &&
356
+ !ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, I3C_RESUME);
357
+}
358
+
359
+static inline uint8_t dw_i3c_fifo_threshold_from_reg(uint8_t regval)
360
+{
361
+ return regval = regval ? (2 << regval) : 1;
362
+}
363
+
364
static void dw_i3c_update_irq(DWI3C *s)
365
{
366
bool level = !!(s->regs[R_INTR_SIGNAL_EN] & s->regs[R_INTR_STATUS]);
367
qemu_set_irq(s->irq, level);
368
}
369
370
+static void dw_i3c_end_transfer(DWI3C *s, bool is_i2c)
371
+{
372
+ if (is_i2c) {
373
+ legacy_i2c_end_transfer(s->bus);
374
+ } else {
375
+ i3c_end_transfer(s->bus);
376
+ }
377
+}
378
+
379
+static int dw_i3c_send_start(DWI3C *s, uint8_t addr, bool is_recv, bool is_i2c)
380
+{
381
+ int ret;
382
+
383
+ if (is_i2c) {
384
+ ret = legacy_i2c_start_transfer(s->bus, addr, is_recv);
385
+ } else {
386
+ ret = i3c_start_transfer(s->bus, addr, is_recv);
387
+ }
388
+ if (ret) {
389
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
390
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: NACKed on TX with addr 0x%.2x\n",
391
+ path, addr);
392
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
393
+ DW_I3C_TRANSFER_STATE_HALT);
394
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
395
+ DW_I3C_TRANSFER_STATUS_HALT);
396
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TRANSFER_ERR, 1);
397
+ ARRAY_FIELD_DP32(s->regs, DEVICE_CTRL, I3C_RESUME, 1);
398
+ }
399
+
400
+ return ret;
401
+}
402
+
403
+static int dw_i3c_send(DWI3C *s, const uint8_t *data, uint32_t num_to_send,
404
+ uint32_t *num_sent, bool is_i2c)
405
+{
406
+ int ret;
407
+ uint32_t i;
408
+
409
+ *num_sent = 0;
410
+ if (is_i2c) {
411
+ /* Legacy I2C must be byte-by-byte. */
412
+ for (i = 0; i < num_to_send; i++) {
413
+ ret = legacy_i2c_send(s->bus, data[i]);
414
+ if (ret) {
415
+ break;
416
+ }
417
+ (*num_sent)++;
418
+ }
419
+ } else {
420
+ ret = i3c_send(s->bus, data, num_to_send, num_sent);
421
+ }
422
+ if (ret) {
423
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
424
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: NACKed sending byte 0x%.2x\n",
425
+ path, data[*num_sent]);
426
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
427
+ DW_I3C_TRANSFER_STATE_HALT);
428
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
429
+ DW_I3C_TRANSFER_STATUS_HALT);
430
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TRANSFER_ERR, 1);
431
+ ARRAY_FIELD_DP32(s->regs, DEVICE_CTRL, I3C_RESUME, 1);
432
+ }
433
+
434
+ trace_dw_i3c_send(s->cfg.id, *num_sent);
435
+
436
+ return ret;
437
+}
438
+
439
+static int dw_i3c_send_byte(DWI3C *s, uint8_t byte, bool is_i2c)
440
+{
441
+ /*
442
+ * Ignored, the caller will know if we sent 0 or 1 bytes depending on if
443
+ * we were ACKed/NACKed.
444
+ */
445
+ uint32_t num_sent;
446
+ return dw_i3c_send(s, &byte, 1, &num_sent, is_i2c);
447
+}
448
+
449
+static int dw_i3c_recv_data(DWI3C *s, bool is_i2c, uint8_t *data,
450
+ uint16_t num_to_read, uint32_t *num_read)
451
+{
452
+ int ret;
453
+
454
+ if (is_i2c) {
455
+ for (uint16_t i = 0; i < num_to_read; i++) {
456
+ data[i] = legacy_i2c_recv(s->bus);
457
+ }
458
+ /* I2C devices can neither NACK a read, nor end transfers early. */
459
+ *num_read = num_to_read;
460
+ trace_dw_i3c_recv_data(s->cfg.id, *num_read);
461
+ return 0;
462
+ }
463
+ /* I3C devices can NACK if the controller sends an unsupported CCC. */
464
+ ret = i3c_recv(s->bus, data, num_to_read, num_read);
465
+ if (ret) {
466
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: NACKed receiving byte\n",
467
+ object_get_canonical_path(OBJECT(s)));
468
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
469
+ DW_I3C_TRANSFER_STATE_HALT);
470
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
471
+ DW_I3C_TRANSFER_STATUS_HALT);
472
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TRANSFER_ERR, 1);
473
+ ARRAY_FIELD_DP32(s->regs, DEVICE_CTRL, I3C_RESUME, 1);
474
+ }
475
+
476
+ trace_dw_i3c_recv_data(s->cfg.id, *num_read);
477
+
478
+ return ret;
479
+}
480
+
481
+static inline bool dw_i3c_target_is_i2c(DWI3C *s, uint16_t offset)
482
+{
483
+ /* / sizeof(uint32_t) because we're indexing into our 32-bit reg array. */
484
+ uint16_t dev_index = (ARRAY_FIELD_EX32(s->regs, DEVICE_ADDR_TABLE_POINTER,
485
+ ADDR) / sizeof(uint32_t)) + offset;
486
+ return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
487
+ LEGACY_I2C_DEVICE);
488
+}
489
+
490
+static uint8_t dw_i3c_target_addr(DWI3C *s, uint16_t offset)
491
+{
492
+ if (offset > s->cfg.num_addressable_devices) {
493
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
494
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Device addr table offset %d out of "
495
+ "bounds\n", path, offset);
496
+ /* If we're out of bounds, return an address of 0. */
497
+ return 0;
498
+ }
499
+
500
+ /* / sizeof(uint32_t) because we're indexing into our 32-bit reg array. */
501
+ uint16_t dev_index = (ARRAY_FIELD_EX32(s->regs, DEVICE_ADDR_TABLE_POINTER,
502
+ ADDR) / sizeof(uint32_t)) + offset;
503
+ /* I2C devices use a static address. */
504
+ if (dw_i3c_target_is_i2c(s, offset)) {
505
+ return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
506
+ DEV_STATIC_ADDR);
507
+ }
508
+ return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1,
509
+ DEV_DYNAMIC_ADDR);
510
+}
511
+
512
static uint32_t dw_i3c_intr_status_r(DWI3C *s)
513
{
514
/* Only return the status whose corresponding EN bits are set. */
543
dw_i3c_update_irq(s);
544
}
545
546
+static uint32_t dw_i3c_pop_rx(DWI3C *s)
547
+{
548
+ if (fifo32_is_empty(&s->rx_queue)) {
549
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
550
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to read RX FIFO when empty\n",
551
+ path);
552
+ return 0;
553
+ }
554
+
555
+ uint32_t val = fifo32_pop(&s->rx_queue);
556
+ ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, RX_BUF_BLR,
557
+ fifo32_num_used(&s->rx_queue));
558
+
559
+ /* Threshold is 2^RX_BUF_THLD. */
560
+ uint8_t threshold = ARRAY_FIELD_EX32(s->regs, DATA_BUFFER_THLD_CTRL,
561
+ RX_BUF_THLD);
562
+ threshold = dw_i3c_fifo_threshold_from_reg(threshold);
563
+ if (fifo32_num_used(&s->rx_queue) < threshold) {
564
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RX_THLD, 0);
565
+ dw_i3c_update_irq(s);
566
+ }
567
+
568
+ trace_dw_i3c_pop_rx(s->cfg.id, val);
569
+ return val;
570
+}
571
+
572
+static uint32_t dw_i3c_resp_queue_port_r(DWI3C *s)
573
+{
574
+ if (fifo32_is_empty(&s->resp_queue)) {
575
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
576
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to read response FIFO when "
577
+ "empty\n", path);
578
+ return 0;
579
+ }
580
+
581
+ uint32_t val = fifo32_pop(&s->resp_queue);
582
+ ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, RESP_BUF_BLR,
583
+ fifo32_num_used(&s->resp_queue));
584
+
585
+ /* Threshold is the register value + 1. */
586
+ uint8_t threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
587
+ RESP_BUF_THLD) + 1;
588
+ if (fifo32_num_used(&s->resp_queue) < threshold) {
589
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RESP_RDY, 0);
590
+ dw_i3c_update_irq(s);
591
+ }
592
+
593
+ return val;
594
+}
595
+
596
static uint64_t dw_i3c_read(void *opaque, hwaddr offset, unsigned size)
597
{
598
DWI3C *s = DW_I3C(opaque);
609
case R_INTR_STATUS:
610
value = dw_i3c_intr_status_r(s);
611
break;
612
+ case R_RX_TX_DATA_PORT:
613
+ value = dw_i3c_pop_rx(s);
614
+ break;
615
+ case R_RESPONSE_QUEUE_PORT:
616
+ value = dw_i3c_resp_queue_port_r(s);
617
+ break;
618
default:
619
value = s->regs[addr];
620
break;
621
}
622
400
- trace_dw_i3c_read(s->id, offset, value);
623
+ trace_dw_i3c_read(s->cfg.id, offset, value);
624
625
return value;
626
}
627
628
+static void dw_i3c_resp_queue_push(DWI3C *s, uint8_t err, uint8_t tid,
629
+ uint8_t ccc_type, uint16_t data_len)
630
+{
631
+ uint32_t val = 0;
632
+ val = FIELD_DP32(val, RESPONSE_QUEUE_PORT, ERR_STATUS, err);
633
+ val = FIELD_DP32(val, RESPONSE_QUEUE_PORT, TID, tid);
634
+ val = FIELD_DP32(val, RESPONSE_QUEUE_PORT, CCCT, ccc_type);
635
+ val = FIELD_DP32(val, RESPONSE_QUEUE_PORT, DL, data_len);
636
+ if (!fifo32_is_full(&s->resp_queue)) {
637
+ trace_dw_i3c_resp_queue_push(s->cfg.id, val);
638
+ fifo32_push(&s->resp_queue, val);
639
+ }
640
+
641
+ ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, RESP_BUF_BLR,
642
+ fifo32_num_used(&s->resp_queue));
643
+ /* Threshold is the register value + 1. */
644
+ uint8_t threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
645
+ RESP_BUF_THLD) + 1;
646
+ if (fifo32_num_used(&s->resp_queue) >= threshold) {
647
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RESP_RDY, 1);
648
+ dw_i3c_update_irq(s);
649
+ }
650
+}
651
+
652
+static void dw_i3c_push_tx(DWI3C *s, uint32_t val)
653
+{
654
+ if (fifo32_is_full(&s->tx_queue)) {
655
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to push to TX FIFO when "
656
+ "full\n", object_get_canonical_path(OBJECT(s)));
657
+ return;
658
+ }
659
+
660
+ trace_dw_i3c_push_tx(s->cfg.id, val);
661
+ fifo32_push(&s->tx_queue, val);
662
+ ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC,
663
+ fifo32_num_free(&s->tx_queue));
664
+
665
+ /* Threshold is 2^TX_BUF_THLD. */
666
+ uint8_t empty_threshold = ARRAY_FIELD_EX32(s->regs, DATA_BUFFER_THLD_CTRL,
667
+ TX_BUF_THLD);
668
+ empty_threshold =
669
+ dw_i3c_fifo_threshold_from_reg(empty_threshold);
670
+ if (fifo32_num_free(&s->tx_queue) < empty_threshold) {
671
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TX_THLD, 0);
672
+ dw_i3c_update_irq(s);
673
+ }
674
+}
675
+
676
+static uint32_t dw_i3c_pop_tx(DWI3C *s)
677
+{
678
+ if (fifo32_is_empty(&s->tx_queue)) {
679
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
680
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to pop from TX FIFO when "
681
+ "empty\n", path);
682
+ return 0;
683
+ }
684
+
685
+ uint32_t val = fifo32_pop(&s->tx_queue);
686
+ trace_dw_i3c_pop_tx(s->cfg.id, val);
687
+ ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC,
688
+ fifo32_num_free(&s->tx_queue));
689
+
690
+ /* Threshold is 2^TX_BUF_THLD. */
691
+ uint8_t empty_threshold = ARRAY_FIELD_EX32(s->regs, DATA_BUFFER_THLD_CTRL,
692
+ TX_BUF_THLD);
693
+ empty_threshold =
694
+ dw_i3c_fifo_threshold_from_reg(empty_threshold);
695
+ if (fifo32_num_free(&s->tx_queue) >= empty_threshold) {
696
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TX_THLD, 1);
697
+ dw_i3c_update_irq(s);
698
+ }
699
+ return val;
700
+}
701
+
702
+static void dw_i3c_push_rx(DWI3C *s, uint32_t val)
703
+{
704
+ if (fifo32_is_full(&s->rx_queue)) {
705
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
706
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to push to RX FIFO when "
707
+ "full\n", path);
708
+ return;
709
+ }
710
+ trace_dw_i3c_push_rx(s->cfg.id, val);
711
+ fifo32_push(&s->rx_queue, val);
712
+
713
+ ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, RX_BUF_BLR,
714
+ fifo32_num_used(&s->rx_queue));
715
+ /* Threshold is 2^RX_BUF_THLD. */
716
+ uint8_t threshold = ARRAY_FIELD_EX32(s->regs, DATA_BUFFER_THLD_CTRL,
717
+ RX_BUF_THLD);
718
+ threshold = dw_i3c_fifo_threshold_from_reg(threshold);
719
+ if (fifo32_num_used(&s->rx_queue) >= threshold) {
720
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, RX_THLD, 1);
721
+ dw_i3c_update_irq(s);
722
+ }
723
+}
724
+
725
+static void dw_i3c_short_transfer(DWI3C *s, DWI3CTransferCmd cmd,
726
+ DWI3CShortArg arg)
727
+{
728
+ uint8_t err = DW_I3C_RESP_QUEUE_ERR_NONE;
729
+ uint8_t addr = dw_i3c_target_addr(s, cmd.dev_index);
730
+ bool is_i2c = dw_i3c_target_is_i2c(s, cmd.dev_index);
731
+ uint8_t data[4]; /* Max we can send on a short transfer is 4 bytes. */
732
+ uint8_t len = 0;
733
+ uint32_t bytes_sent; /* Ignored on short transfers. */
734
+
735
+ /* Can't do reads on a short transfer. */
736
+ if (cmd.rnw) {
737
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
738
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Cannot do a read on a short "
739
+ "transfer\n", path);
740
+ return;
741
+ }
742
+
743
+ if (dw_i3c_send_start(s, addr, /*is_recv=*/false, is_i2c)) {
744
+ err = DW_I3C_RESP_QUEUE_ERR_I2C_NACK;
745
+ goto transfer_done;
746
+ }
747
+
748
+ /* Are we sending a command? */
749
+ if (cmd.cp) {
750
+ data[len] = cmd.cmd;
751
+ len++;
752
+ /*
753
+ * byte0 is the defining byte for a command, and is only sent if a
754
+ * command is present and if the command has a defining byte present.
755
+ * (byte_strb & 0x01) is always treated as set by the controller, and is
756
+ * ignored.
757
+ */
758
+ if (cmd.dbp) {
759
+ data[len] += arg.byte0;
760
+ len++;
761
+ }
762
+ }
763
+
764
+ /* Send the bytes passed in the argument. */
765
+ if (arg.byte_strb & 0x02) {
766
+ data[len] = arg.byte1;
767
+ len++;
768
+ }
769
+ if (arg.byte_strb & 0x04) {
770
+ data[len] = arg.byte2;
771
+ len++;
772
+ }
773
+
774
+ if (dw_i3c_send(s, data, len, &bytes_sent, is_i2c)) {
775
+ err = DW_I3C_RESP_QUEUE_ERR_I2C_NACK;
776
+ } else {
777
+ /* Only go to an idle state on a successful transfer. */
778
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
779
+ DW_I3C_TRANSFER_STATE_IDLE);
780
+ }
781
+
782
+transfer_done:
783
+ if (cmd.toc) {
784
+ dw_i3c_end_transfer(s, is_i2c);
785
+ }
786
+ if (cmd.roc) {
787
+ /*
788
+ * ccc_type is always 0 in controller mode, data_len is 0 in short
789
+ * transfers.
790
+ */
791
+ dw_i3c_resp_queue_push(s, err, cmd.tid, /*ccc_type=*/0,
792
+ /*data_len=*/0);
793
+ }
794
+}
795
+
796
+/* Returns number of bytes transmitted. */
797
+static uint16_t dw_i3c_tx(DWI3C *s, uint16_t num, bool is_i2c)
798
+{
799
+ uint16_t bytes_sent = 0;
800
+ union {
801
+ uint8_t b[sizeof(uint32_t)];
802
+ uint32_t val;
803
+ } val32;
804
+
805
+ while (bytes_sent < num) {
806
+ val32.val = dw_i3c_pop_tx(s);
807
+ for (uint8_t i = 0; i < sizeof(val32.val); i++) {
808
+ if (dw_i3c_send_byte(s, val32.b[i], is_i2c)) {
809
+ return bytes_sent;
810
+ }
811
+ bytes_sent++;
812
+
813
+ /* We're not sending the full 32-bits, break early. */
814
+ if (bytes_sent >= num) {
815
+ break;
816
+ }
817
+ }
818
+ }
819
+
820
+ return bytes_sent;
821
+}
822
+
823
+/* Returns number of bytes received. */
824
+static uint16_t dw_i3c_rx(DWI3C *s, uint16_t num, bool is_i2c)
825
+{
826
+ /*
827
+ * Allocate a temporary buffer to read data from the target.
828
+ * Zero it and word-align it as well in case we're reading unaligned data.
829
+ */
830
+ g_autofree uint8_t *data = g_new0(uint8_t, num + (4 - (num & 0x03)));
831
+ uint32_t *data32 = (uint32_t *)data;
832
+ /*
833
+ * 32-bits since the I3C API wants a 32-bit number, even though the
834
+ * controller can only do 16-bit transfers.
835
+ */
836
+ uint32_t num_read = 0;
837
+
838
+ /* Can NACK if the target receives an unsupported CCC. */
839
+ if (dw_i3c_recv_data(s, is_i2c, data, num, &num_read)) {
840
+ return 0;
841
+ }
842
+
843
+ for (uint16_t i = 0; i < num_read / 4; i++) {
844
+ dw_i3c_push_rx(s, *data32);
845
+ data32++;
846
+ }
847
+ /*
848
+ * If we're pushing data that isn't 32-bit aligned, push what's left.
849
+ * It's software's responsibility to know what bits are valid in the partial
850
+ * data.
851
+ */
852
+ if (num_read & 0x03) {
853
+ dw_i3c_push_rx(s, *data32);
854
+ }
855
+
856
+ return num_read;
857
+}
858
+
859
+static int dw_i3c_transfer_ccc(DWI3C *s, DWI3CTransferCmd cmd,
860
+ DWI3CTransferArg arg)
861
+{
862
+ /* CCC start is always a write. CCCs cannot be done on I2C devices. */
863
+ if (dw_i3c_send_start(s, I3C_BROADCAST, /*is_recv=*/false,
864
+ /*is_i2c=*/false)) {
865
+ return DW_I3C_RESP_QUEUE_ERR_BROADCAST_NACK;
866
+ }
867
+ trace_dw_i3c_transfer_ccc(s->cfg.id, cmd.cmd);
868
+ if (dw_i3c_send_byte(s, cmd.cmd, /*is_i2c=*/false)) {
869
+ return DW_I3C_RESP_QUEUE_ERR_I2C_NACK;
870
+ }
871
+
872
+ /* On a direct CCC, we do a restart and then send the target's address. */
873
+ if (CCC_IS_DIRECT(cmd.cmd)) {
874
+ bool is_recv = cmd.rnw;
875
+ uint8_t addr = dw_i3c_target_addr(s, cmd.dev_index);
876
+ if (dw_i3c_send_start(s, addr, is_recv, /*is_i2c=*/false)) {
877
+ return DW_I3C_RESP_QUEUE_ERR_BROADCAST_NACK;
878
+ }
879
+ }
880
+
881
+ return DW_I3C_RESP_QUEUE_ERR_NONE;
882
+}
883
+
884
+static void dw_i3c_transfer(DWI3C *s, DWI3CTransferCmd cmd,
885
+ DWI3CTransferArg arg)
886
+{
887
+ bool is_recv = cmd.rnw;
888
+ uint8_t err = DW_I3C_RESP_QUEUE_ERR_NONE;
889
+ uint8_t addr = dw_i3c_target_addr(s, cmd.dev_index);
890
+ bool is_i2c = dw_i3c_target_is_i2c(s, cmd.dev_index);
891
+ uint16_t bytes_transferred = 0;
892
+
893
+ if (cmd.cp) {
894
+ /* We're sending a CCC. */
895
+ err = dw_i3c_transfer_ccc(s, cmd, arg);
896
+ if (err != DW_I3C_RESP_QUEUE_ERR_NONE) {
897
+ goto transfer_done;
898
+ }
899
+ } else {
900
+ if (ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, I3C_BROADCAST_ADDR_INC) &&
901
+ is_i2c == false) {
902
+ if (dw_i3c_send_start(s, I3C_BROADCAST,
903
+ /*is_recv=*/false, is_i2c)) {
904
+ err = DW_I3C_RESP_QUEUE_ERR_I2C_NACK;
905
+ goto transfer_done;
906
+ }
907
+ }
908
+ /* Otherwise we're doing a private transfer. */
909
+ if (dw_i3c_send_start(s, addr, is_recv, is_i2c)) {
910
+ err = DW_I3C_RESP_QUEUE_ERR_I2C_NACK;
911
+ goto transfer_done;
912
+ }
913
+ }
914
+
915
+ if (is_recv) {
916
+ bytes_transferred = dw_i3c_rx(s, arg.data_len, is_i2c);
917
+ } else {
918
+ bytes_transferred = dw_i3c_tx(s, arg.data_len, is_i2c);
919
+ }
920
+
921
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
922
+ DW_I3C_TRANSFER_STATE_IDLE);
923
+
924
+transfer_done:
925
+ if (cmd.toc) {
926
+ dw_i3c_end_transfer(s, is_i2c);
927
+ }
928
+ if (cmd.roc) {
929
+ /*
930
+ * data_len is the number of bytes that still need to be TX'd, or the
931
+ * number of bytes RX'd.
932
+ */
933
+ uint16_t data_len = is_recv ? bytes_transferred : arg.data_len -
934
+ bytes_transferred;
935
+ /* CCCT is always 0 in controller mode. */
936
+ dw_i3c_resp_queue_push(s, err, cmd.tid, /*ccc_type=*/0,
937
+ data_len);
938
+ }
939
+
940
+ dw_i3c_update_irq(s);
941
+}
942
+
943
+static void dw_i3c_transfer_cmd(DWI3C *s, DWI3CTransferCmd cmd,
944
+ DWI3CCmdQueueData arg)
945
+{
946
+ uint8_t arg_attr = FIELD_EX32(arg.word, COMMAND_QUEUE_PORT, CMD_ATTR);
947
+
948
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CMD_TID, cmd.tid);
949
+
950
+ /* User is trying to do HDR transfers, see if we can do them. */
951
+ if (cmd.speed == 0x06 && !dw_i3c_has_hdr_ddr(s)) {
952
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
953
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: HDR DDR is not supported\n", path);
954
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
955
+ DW_I3C_TRANSFER_STATE_HALT);
956
+ return;
957
+ }
958
+ if (cmd.speed == 0x05 && !dw_i3c_has_hdr_ts(s)) {
959
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
960
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: HDR TS is not supported\n", path);
961
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
962
+ DW_I3C_TRANSFER_STATE_HALT);
963
+ return;
964
+ }
965
+
966
+ if (arg_attr == DW_I3C_CMD_ATTR_TRANSFER_ARG) {
967
+ dw_i3c_transfer(s, cmd, arg.transfer_arg);
968
+ } else if (arg_attr == DW_I3C_CMD_ATTR_SHORT_DATA_ARG) {
969
+ dw_i3c_short_transfer(s, cmd, arg.short_arg);
970
+ } else {
971
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
972
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown command queue cmd_attr 0x%x"
973
+ "\n", path, arg_attr);
974
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
975
+ DW_I3C_TRANSFER_STATE_HALT);
976
+ }
977
+}
978
+
979
+static void dw_i3c_update_char_table(DWI3C *s, uint8_t offset, uint64_t pid,
980
+ uint8_t bcr, uint8_t dcr, uint8_t addr)
981
+{
982
+ if (offset > s->cfg.num_addressable_devices) {
983
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
984
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Device char table offset %d out of "
985
+ "bounds\n", path, offset);
986
+ /* If we're out of bounds, do nothing. */
987
+ return;
988
+ }
989
+
990
+ /*
991
+ * Each device offset is 128 bits apart in the table, since each device gets
992
+ * 4 * 32-bits of entries in the table.
993
+ * / sizeof(uint32_t) because we're indexing into our 32-bit reg array.
994
+ */
995
+ uint16_t dev_index = (ARRAY_FIELD_EX32(s->regs, DEV_CHAR_TABLE_POINTER,
996
+ P_DEV_CHAR_TABLE_START_ADDR) /
997
+ sizeof(uint32_t)) +
998
+ (offset * sizeof(uint32_t));
999
+ s->regs[dev_index] = pid & 0xffffffff;
1000
+ pid >>= 32;
1001
+ s->regs[dev_index + 1] = FIELD_DP32(s->regs[dev_index + 1],
1002
+ DEVICE_CHARACTERISTIC_TABLE_LOC2,
1003
+ MSB_PID, pid);
1004
+ s->regs[dev_index + 2] = FIELD_DP32(s->regs[dev_index + 2],
1005
+ DEVICE_CHARACTERISTIC_TABLE_LOC3, DCR,
1006
+ dcr);
1007
+ s->regs[dev_index + 2] = FIELD_DP32(s->regs[dev_index + 2],
1008
+ DEVICE_CHARACTERISTIC_TABLE_LOC3, BCR,
1009
+ bcr);
1010
+ s->regs[dev_index + 3] = FIELD_DP32(s->regs[dev_index + 3],
1011
+ DEVICE_CHARACTERISTIC_TABLE_LOC4,
1012
+ DEV_DYNAMIC_ADDR, addr);
1013
+
1014
+ /* Increment PRESENT_DEV_CHAR_TABLE_INDEX. */
1015
+ uint8_t idx = ARRAY_FIELD_EX32(s->regs, DEV_CHAR_TABLE_POINTER,
1016
+ PRESENT_DEV_CHAR_TABLE_INDEX);
1017
+ /* Increment and rollover. */
1018
+ idx++;
1019
+ if (idx >= ARRAY_FIELD_EX32(s->regs, DEV_CHAR_TABLE_POINTER,
1020
+ DEV_CHAR_TABLE_DEPTH) / 4) {
1021
+ idx = 0;
1022
+ }
1023
+ ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER,
1024
+ PRESENT_DEV_CHAR_TABLE_INDEX, idx);
1025
+}
1026
+
1027
+static void dw_i3c_addr_assign_cmd(DWI3C *s, DWI3CAddrAssignCmd cmd)
1028
+{
1029
+ uint8_t i = 0;
1030
+ uint8_t err = DW_I3C_RESP_QUEUE_ERR_NONE;
1031
+
1032
+ /* Tell everyone to ENTDAA. If these error, no one is on the bus. */
1033
+ if (dw_i3c_send_start(s, I3C_BROADCAST, /*is_recv=*/false,
1034
+ /*is_i2c=*/false)) {
1035
+ err = DW_I3C_RESP_QUEUE_ERR_BROADCAST_NACK;
1036
+ goto transfer_done;
1037
+ }
1038
+ if (dw_i3c_send_byte(s, cmd.cmd, /*is_i2c=*/false)) {
1039
+ err = DW_I3C_RESP_QUEUE_ERR_BROADCAST_NACK;
1040
+ goto transfer_done;
1041
+ }
1042
+
1043
+ /* Go through each device in the table and assign it an address. */
1044
+ for (i = 0; i < cmd.dev_count; i++) {
1045
+ uint8_t addr = dw_i3c_target_addr(s, cmd.dev_index + i);
1046
+ union {
1047
+ uint64_t pid:48;
1048
+ uint8_t bcr;
1049
+ uint8_t dcr;
1050
+ uint32_t w[2];
1051
+ uint8_t b[8];
1052
+ } target_info;
1053
+
1054
+ /* If this fails, there was no one left to ENTDAA. */
1055
+ if (dw_i3c_send_start(s, I3C_BROADCAST, /*is_recv=*/false,
1056
+ /*is_i2c=*/false)) {
1057
+ err = DW_I3C_RESP_QUEUE_ERR_BROADCAST_NACK;
1058
+ break;
1059
+ }
1060
+
1061
+ /*
1062
+ * In ENTDAA, we read 8 bytes from the target, which will be the
1063
+ * target's PID, BCR, and DCR. After that, we send it the dynamic
1064
+ * address.
1065
+ * Don't bother checking the number of bytes received, it must send 8
1066
+ * bytes during ENTDAA.
1067
+ */
1068
+ uint32_t num_read;
1069
+ if (dw_i3c_recv_data(s, /*is_i2c=*/false, target_info.b,
1070
+ I3C_ENTDAA_SIZE, &num_read)) {
1071
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1072
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Target NACKed ENTDAA CCC\n",
1073
+ path);
1074
+ err = DW_I3C_RESP_QUEUE_ERR_DAA_NACK;
1075
+ goto transfer_done;
1076
+ }
1077
+ if (dw_i3c_send_byte(s, addr, /*is_i2c=*/false)) {
1078
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1079
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Target NACKed addr 0x%.2x "
1080
+ "during ENTDAA\n", path, addr);
1081
+ err = DW_I3C_RESP_QUEUE_ERR_DAA_NACK;
1082
+ break;
1083
+ }
1084
+ dw_i3c_update_char_table(s, cmd.dev_index + i,
1085
+ target_info.pid, target_info.bcr,
1086
+ target_info.dcr, addr);
1087
+
1088
+ /* Push the PID, BCR, and DCR to the RX queue. */
1089
+ dw_i3c_push_rx(s, target_info.w[0]);
1090
+ dw_i3c_push_rx(s, target_info.w[1]);
1091
+ }
1092
+
1093
+transfer_done:
1094
+ /* Do we send a STOP? */
1095
+ if (cmd.toc) {
1096
+ dw_i3c_end_transfer(s, /*is_i2c=*/false);
1097
+ }
1098
+ /*
1099
+ * For addr assign commands, the length field is the number of devices
1100
+ * left to assign. CCCT is always 0 in controller mode.
1101
+ */
1102
+ if (cmd.roc) {
1103
+ dw_i3c_resp_queue_push(s, err, cmd.tid, /*ccc_type=*/0,
1104
+ cmd.dev_count - i);
1105
+ }
1106
+}
1107
+
1108
+static uint32_t dw_i3c_cmd_queue_pop(DWI3C *s)
1109
+{
1110
+ if (fifo32_is_empty(&s->cmd_queue)) {
1111
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1112
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to dequeue command queue "
1113
+ "when it was empty\n", path);
1114
+ return 0;
1115
+ }
1116
+ uint32_t val = fifo32_pop(&s->cmd_queue);
1117
+
1118
+ uint8_t empty_threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
1119
+ CMD_BUF_EMPTY_THLD);
1120
+ uint8_t cmd_queue_empty_loc = ARRAY_FIELD_EX32(s->regs,
1121
+ QUEUE_STATUS_LEVEL,
1122
+ CMD_QUEUE_EMPTY_LOC);
1123
+ cmd_queue_empty_loc++;
1124
+ ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC,
1125
+ cmd_queue_empty_loc);
1126
+ if (cmd_queue_empty_loc >= empty_threshold) {
1127
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, CMD_QUEUE_RDY, 1);
1128
+ dw_i3c_update_irq(s);
1129
+ }
1130
+
1131
+ return val;
1132
+}
1133
+
1134
+static void dw_i3c_cmd_queue_execute(DWI3C *s)
1135
+{
1136
+ ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
1137
+ DW_I3C_TRANSFER_STATE_IDLE);
1138
+ if (!dw_i3c_can_transmit(s)) {
1139
+ return;
1140
+ }
1141
+
1142
+ /*
1143
+ * We only start executing when a command is passed into the FIFO.
1144
+ * We expect there to be a multiple of 2 items in the queue. The first item
1145
+ * should be an argument to a command, and the command should be the second
1146
+ * item.
1147
+ */
1148
+ if (fifo32_num_used(&s->cmd_queue) & 1) {
1149
+ return;
1150
+ }
1151
+
1152
+ while (!fifo32_is_empty(&s->cmd_queue)) {
1153
+ DWI3CCmdQueueData arg;
1154
+ arg.word = dw_i3c_cmd_queue_pop(s);
1155
+ DWI3CCmdQueueData cmd;
1156
+ cmd.word = dw_i3c_cmd_queue_pop(s);
1157
+ trace_dw_i3c_cmd_queue_execute(s->cfg.id, cmd.word, arg.word);
1158
+
1159
+ uint8_t cmd_attr = FIELD_EX32(cmd.word, COMMAND_QUEUE_PORT, CMD_ATTR);
1160
+ switch (cmd_attr) {
1161
+ case DW_I3C_CMD_ATTR_TRANSFER_CMD:
1162
+ dw_i3c_transfer_cmd(s, cmd.transfer_cmd, arg);
1163
+ break;
1164
+ case DW_I3C_CMD_ATTR_ADDR_ASSIGN_CMD:
1165
+ /* Arg is discarded for addr assign commands. */
1166
+ dw_i3c_addr_assign_cmd(s, cmd.addr_assign_cmd);
1167
+ break;
1168
+ case DW_I3C_CMD_ATTR_TRANSFER_ARG:
1169
+ case DW_I3C_CMD_ATTR_SHORT_DATA_ARG:
1170
+ {
1171
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1172
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Command queue received "
1173
+ "argument packet when it expected a command "
1174
+ "packet\n", path);
1175
+ }
1176
+ break;
1177
+ default:
1178
+ /*
1179
+ * The caller's check before queueing an item should prevent this
1180
+ * from happening.
1181
+ */
1182
+ g_assert_not_reached();
1183
+ break;
1184
+ }
1185
+ }
1186
+}
1187
+
1188
+static void dw_i3c_cmd_queue_push(DWI3C *s, uint32_t val)
1189
+{
1190
+ if (fifo32_is_full(&s->cmd_queue)) {
1191
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1192
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Command queue received packet when "
1193
+ "already full\n", path);
1194
+ return;
1195
+ }
1196
+ trace_dw_i3c_cmd_queue_push(s->cfg.id, val);
1197
+ fifo32_push(&s->cmd_queue, val);
1198
+
1199
+ uint8_t empty_threshold = ARRAY_FIELD_EX32(s->regs, QUEUE_THLD_CTRL,
1200
+ CMD_BUF_EMPTY_THLD);
1201
+ uint8_t cmd_queue_empty_loc = ARRAY_FIELD_EX32(s->regs,
1202
+ QUEUE_STATUS_LEVEL,
1203
+ CMD_QUEUE_EMPTY_LOC);
1204
+ if (cmd_queue_empty_loc) {
1205
+ cmd_queue_empty_loc--;
1206
+ ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC,
1207
+ cmd_queue_empty_loc);
1208
+ }
1209
+ if (cmd_queue_empty_loc < empty_threshold) {
1210
+ ARRAY_FIELD_DP32(s->regs, INTR_STATUS, CMD_QUEUE_RDY, 0);
1211
+ dw_i3c_update_irq(s);
1212
+ }
1213
+}
1214
+
1215
+static void dw_i3c_cmd_queue_port_w(DWI3C *s, uint32_t val)
1216
+{
1217
+ uint8_t cmd_attr = FIELD_EX32(val, COMMAND_QUEUE_PORT, CMD_ATTR);
1218
+
1219
+ switch (cmd_attr) {
1220
+ /* If a command is received we can start executing it. */
1221
+ case DW_I3C_CMD_ATTR_TRANSFER_CMD:
1222
+ case DW_I3C_CMD_ATTR_ADDR_ASSIGN_CMD:
1223
+ dw_i3c_cmd_queue_push(s, val);
1224
+ dw_i3c_cmd_queue_execute(s);
1225
+ break;
1226
+ /* If we get an argument just push it. */
1227
+ case DW_I3C_CMD_ATTR_TRANSFER_ARG:
1228
+ case DW_I3C_CMD_ATTR_SHORT_DATA_ARG:
1229
+ dw_i3c_cmd_queue_push(s, val);
1230
+ break;
1231
+ default:
1232
+ {
1233
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1234
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Command queue received packet "
1235
+ "with unknown cmd attr 0x%x\n", path, cmd_attr);
1236
+ }
1237
+ break;
1238
+ }
1239
+}
1240
+
1241
static void dw_i3c_write(void *opaque, hwaddr offset, uint64_t value,
1242
unsigned size)
1243
{
1245
uint32_t addr = offset >> 2;
1246
uint32_t val32 = (uint32_t)value;
1247
412
- trace_dw_i3c_write(s->id, offset, value);
1248
+ trace_dw_i3c_write(s->cfg.id, offset, value);
1249
1250
val32 &= ~dw_i3c_ro[addr];
1251
switch (addr) {
1269
__func__, offset, value);
1270
break;
1271
case R_RX_TX_DATA_PORT:
1272
+ dw_i3c_push_tx(s, val32);
1273
+ break;
1274
+ case R_COMMAND_QUEUE_PORT:
1275
+ dw_i3c_cmd_queue_port_w(s, val32);
1276
break;
1277
case R_RESET_CTRL:
1278
break;
1315
DWI3C *s = DW_I3C(obj);
1316
1317
memcpy(s->regs, dw_i3c_resets, sizeof(s->regs));
1318
+ /*
1319
+ * The user config for these may differ from our resets array, set them
1320
+ * manually.
1321
+ */
1322
+ ARRAY_FIELD_DP32(s->regs, DEVICE_ADDR_TABLE_POINTER, ADDR,
1323
+ s->cfg.dev_addr_table_pointer);
1324
+ ARRAY_FIELD_DP32(s->regs, DEVICE_ADDR_TABLE_POINTER, DEPTH,
1325
+ s->cfg.dev_addr_table_depth);
1326
+ ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER,
1327
+ P_DEV_CHAR_TABLE_START_ADDR,
1328
+ s->cfg.dev_char_table_pointer);
1329
+ ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER, DEV_CHAR_TABLE_DEPTH,
1330
+ s->cfg.dev_char_table_depth);
1331
}
1332
1333
static void dw_i3c_realize(DeviceState *dev, Error **errp)
1334
{
1335
DWI3C *s = DW_I3C(dev);
483
- g_autofree char *name = g_strdup_printf(TYPE_DW_I3C ".%d", s->id);
1336
+ g_autofree char *name = g_strdup_printf(TYPE_DW_I3C ".%d", s->cfg.id);
1337
1338
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
1339
1340
memory_region_init_io(&s->mr, OBJECT(s), &dw_i3c_ops, s, name,
1341
DW_I3C_NR_REGS << 2);
1342
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr);
1343
+
1344
+ fifo32_create(&s->cmd_queue, s->cfg.cmd_resp_queue_capacity_bytes);
1345
+ fifo32_create(&s->resp_queue, s->cfg.cmd_resp_queue_capacity_bytes);
1346
+ fifo32_create(&s->tx_queue, s->cfg.tx_rx_queue_capacity_bytes);
1347
+ fifo32_create(&s->rx_queue, s->cfg.tx_rx_queue_capacity_bytes);
1348
+
1349
+ s->bus = i3c_init_bus(DEVICE(s), name);
1350
}
1351
1352
static const Property dw_i3c_properties[] = {
493
- DEFINE_PROP_UINT8("device-id", DWI3C, id, 0),
1353
+ DEFINE_PROP_UINT8("device-id", DWI3C, cfg.id, 0),
1354
+ DEFINE_PROP_UINT8("command-response-queue-capacity-bytes", DWI3C,
1355
+ cfg.cmd_resp_queue_capacity_bytes, 0x10),
1356
+ DEFINE_PROP_UINT16("tx-rx-queue-capacity-bytes", DWI3C,
1357
+ cfg.tx_rx_queue_capacity_bytes, 0x40),
1358
+ DEFINE_PROP_UINT8("num-addressable-devices", DWI3C,
1359
+ cfg.num_addressable_devices, 8),
1360
+ DEFINE_PROP_UINT16("dev-addr-table-pointer", DWI3C,
1361
+ cfg.dev_addr_table_pointer, 0x280),
1362
+ DEFINE_PROP_UINT16("dev-addr-table-depth", DWI3C,
1363
+ cfg.dev_addr_table_depth, 0x08),
1364
+ DEFINE_PROP_UINT16("dev-char-table-pointer", DWI3C,
1365
+ cfg.dev_char_table_pointer, 0x200),
1366
+ DEFINE_PROP_UINT16("dev-char-table-depth", DWI3C,
1367
+ cfg.dev_char_table_depth, 0x20),
1368
};
1369
1370
static void dw_i3c_class_init(ObjectClass *klass, const void *data)