Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d60d7f1d authored by Kristian Høgsberg's avatar Kristian Høgsberg Committed by Stefan Richter
Browse files

firewire: Implement CSR cycle time and bus time registers.

parent 473d28c7
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ struct fw_ohci {
	int node_id;
	int generation;
	int request_generation;
	u32 bus_seconds;

	/* Spinlock for accessing fw_ohci data.  Never call out of
	 * this driver with this lock held. */
@@ -959,7 +960,7 @@ static void bus_reset_tasklet(unsigned long data)
static irqreturn_t irq_handler(int irq, void *data)
{
	struct fw_ohci *ohci = data;
	u32 event, iso_event;
	u32 event, iso_event, cycle_time;
	int i;

	event = reg_read(ohci, OHCI1394_IntEventClear);
@@ -1002,6 +1003,12 @@ static irqreturn_t irq_handler(int irq, void *data)
		iso_event &= ~(1 << i);
	}

	if (event & OHCI1394_cycle64Seconds) {
		cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
		if ((cycle_time & 0x80000000) == 0)
			ohci->bus_seconds++;
	}

	return IRQ_HANDLED;
}

@@ -1213,6 +1220,19 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
	return retval;
}

static u64
ohci_get_bus_time(struct fw_card *card)
{
	struct fw_ohci *ohci = fw_ohci(card);
	u32 cycle_time;
	u64 bus_time;

	cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
	bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time;

	return bus_time;
}

static int handle_ir_bufferfill_packet(struct context *context,
				       struct descriptor *d,
				       struct descriptor *last)
@@ -1686,6 +1706,7 @@ static const struct fw_card_driver ohci_driver = {
	.send_response		= ohci_send_response,
	.cancel_packet		= ohci_cancel_packet,
	.enable_phys_dma	= ohci_enable_phys_dma,
	.get_bus_time		= ohci_get_bus_time,

	.allocate_iso_context	= ohci_allocate_iso_context,
	.free_iso_context	= ohci_free_iso_context,
@@ -1862,7 +1883,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
		  OHCI1394_RQPkt | OHCI1394_RSPkt |
		  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
		  OHCI1394_isochRx | OHCI1394_isochTx |
		  OHCI1394_masterIntEnable);
		  OHCI1394_masterIntEnable |
		  OHCI1394_cycle64Seconds);

	bus_options = reg_read(ohci, OHCI1394_BusOptions);
	max_receive = (bus_options >> 12) & 0xf;
+60 −1
Original line number Diff line number Diff line
@@ -752,10 +752,65 @@ handle_topology_map(struct fw_card *card, struct fw_request *request,
}

static struct fw_address_handler topology_map = {
	.length			= 0x400,
	.length			= 0x200,
	.address_callback	= handle_topology_map,
};

const struct fw_address_region registers_region =
	{ .start = 0xfffff0000000ull, .end = 0xfffff0000400ull, };

static void
handle_registers(struct fw_card *card, struct fw_request *request,
		 int tcode, int destination, int source,
		 int generation, int speed,
		 unsigned long long offset,
		 void *payload, size_t length, void *callback_data)
{
	int reg = offset - CSR_REGISTER_BASE;
	unsigned long long bus_time;
	__be32 *data = payload;

	switch (reg) {
	case CSR_CYCLE_TIME:
	case CSR_BUS_TIME:
		if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
			fw_send_response(card, request, RCODE_TYPE_ERROR);
			break;
		}

		bus_time = card->driver->get_bus_time(card);
		if (reg == CSR_CYCLE_TIME)
			*data = cpu_to_be32(bus_time);
		else
			*data = cpu_to_be32(bus_time >> 25);
		fw_send_response(card, request, RCODE_COMPLETE);
		break;

	case CSR_BUS_MANAGER_ID:
	case CSR_BANDWIDTH_AVAILABLE:
	case CSR_CHANNELS_AVAILABLE_HI:
	case CSR_CHANNELS_AVAILABLE_LO:
		/* FIXME: these are handled by the OHCI hardware and
		 * the stack never sees these request. If we add
		 * support for a new type of controller that doesn't
		 * handle this in hardware we need to deal with these
		 * transactions. */
		BUG();
		break;

	case CSR_BUSY_TIMEOUT:
		/* FIXME: Implement this. */
	default:
		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
		break;
	}
}

static struct fw_address_handler registers = {
	.length			= 0x400,
	.address_callback	= handle_registers,
};

MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
MODULE_DESCRIPTION("Core IEEE1394 transaction logic");
MODULE_LICENSE("GPL");
@@ -811,6 +866,10 @@ static int __init fw_core_init(void)
					     &topology_map_region);
	BUG_ON(retval < 0);

	retval = fw_core_add_address_handler(&registers,
					     &registers_region);
	BUG_ON(retval < 0);

	/* Add the vendor textual descriptor. */
	retval = fw_core_add_descriptor(&vendor_id_descriptor);
	BUG_ON(retval < 0);
+2 −0
Original line number Diff line number Diff line
@@ -433,6 +433,8 @@ struct fw_card_driver {
	int (*enable_phys_dma) (struct fw_card *card,
				int node_id, int generation);

	u64 (*get_bus_time) (struct fw_card *card);

	struct fw_iso_context *
	(*allocate_iso_context)(struct fw_card *card, int sync, int tags,
				int type, size_t header_size);