On Thu, 12 Dec 2019, at 07:09, Eddie James wrote:
On 12/10/19 9:47 PM, Andrew Jeffery wrote:But what happens as a consequence? We would have a 64 bit address
On Fri, 6 Dec 2019, at 03:45, Eddie James wrote:
+Do we know that this won't wrap?
+static unsigned int aspeed_xdma_ast2600_set_cmd(struct aspeed_xdma *ctx,
+ struct aspeed_xdma_op *op,
+ u32 bmc_addr)
+{
+ u64 cmd = XDMA_CMD_AST2600_CMD_IRQ_BMC |
+ (op->direction ? XDMA_CMD_AST2600_CMD_UPSTREAM : 0);
+ unsigned int line_size;
+ unsigned int nidx = (ctx->cmd_idx + 1) % XDMA_NUM_CMDS;
+ unsigned int line_no = 1;
+ unsigned int pitch = 1;
+ struct aspeed_xdma_cmd *ncmd =
+ &(((struct aspeed_xdma_cmd *)ctx->cmdq)[ctx->cmd_idx]);
+
+ if ((op->host_addr + op->len) & 0xffffffff00000000ULL)
No, but I assume it would be a bad transfer anyway at that point?
but wouldn't enable 64bit addressing, so presumably the hardware
would only use the bottom 32 bits of the address?
Things could get weird yes?
Or is there some failure that would occur before we trigger the transfer?
Is that what you're depending on?
Why is it worth not locking? How is it correct? To answer that way we invoke+You need to take start_lock before writing these members to ensure the
+static void aspeed_xdma_done(struct aspeed_xdma *ctx, bool error)
+{
+ if (ctx->current_client) {
+ ctx->current_client->error = error;
+ ctx->current_client->in_progress = false;
+ ctx->current_client = NULL;
writes are not reordered across acquisition of start_lock in
aspeed_xdma_start() above, unless there's some other guarantee of that?
Unless we get spurious interrupts (as in, the xdma interrupt fires with
no transfer started, and somehow the correct status bits are set), it's
not possible to execute this at the same time as aspeed_xdma_start(). So
I did not try and lock here. Do you think it's worth locking for that
situation?
all kinds of reasoning about multi-processing (interrupt handled on one core
while aspeed_xdma_start() is executing on another), value visibility and
instruction reordering (though as it happens the 2400, 2500 and 2600 are all
in-order). We'll trip ourselves up if there is eventually a switch to out-of-order
execution where the writes might be reordered and delayed until after
start_lock has been acquired in aspeed_xdma_start() by a subseqent transfer.
This line of reasoning is brittle exploitation of properties of the currently used
cores for no benefit. Finishing the DMA op isn't a hot path where you might
want to take some of these risks for performance, so we have almost zero
care for lock contention but we must always be concerned about correctness.
We avoid invoking all of those questions by acquiring the lock.
Fair enough.+As mentioned, this could be any reserved memory range. Also can't we get it as
+ ctx->vga_pool = devm_gen_pool_create(dev, ilog2(PAGE_SIZE), -1, NULL);
+ if (!ctx->vga_pool) {
+ dev_err(dev, "Failed to setup genalloc pool.\n");
+ return -ENOMEM;
+ }
+
+ rc = of_property_read_u32_array(dev->of_node, "vga-mem", vgamem, 2);
a resource rather than parsing a u32 array? Not sure if there's an advantage
but it feels like a better representation.
That doesn't work unfortunately because the VGA memory is not mapped and
the reserved memory subsystem fails to find it.
Right. That's where I was going. I don't expect you to do that as part of this+I disagree with doing this. As mentioned on the bindings it should be up to
+ regmap_update_bits(sdmc, SDMC_REMAP, ctx->chip->sdmc_remap,
+ ctx->chip->sdmc_remap);
the platform integrator to ensure that this is configured appropriately.
Probably so, but then how does one actually configure that elsewhere? Do
you mean add code to the edac driver (and add support for the ast2600)
to read some dts properties to set it?
patch series, but if you could separate this code out into separate patches
(dealing with the sdmc property in the devicetree binding as well) we can at
least concentrate on getting the core XDMA driver in and work out how to
move forward with configuring the memory controller later.
Right, but if you separate it out you'll get my reviewed-by on the core XDMA+/*I still think having a reset action as part of the direction is a bit funky. Can you maybe
+ * aspeed_xdma_direction
+ *
+ * ASPEED_XDMA_DIRECTION_DOWNSTREAM: transfers data from the host to the BMC
+ *
+ * ASPEED_XDMA_DIRECTION_UPSTREAM: transfers data from the BMC to the host
+ *
+ * ASPEED_XDMA_DIRECTION_RESET: resets the XDMA engine
+ */
+enum aspeed_xdma_direction {
+ ASPEED_XDMA_DIRECTION_DOWNSTREAM = 0,
+ ASPEED_XDMA_DIRECTION_UPSTREAM,
+ ASPEED_XDMA_DIRECTION_RESET,
put that in a separate patch so we can debate it later?
I can, but I'm fairly convinced this is the cleanest way to add the
reset functionality.
patches much quicker :) You can convince me about it in slow-time
Cheers,
Andrew