mhi: core: Enable parsing of dev window from dt
Enable parsing of device window size from device tree and calculating the appropriate addressing limitations. Change-Id: I252a593a74f0cc00e6295a45d4d13db6c79cdfca Signed-off-by: Andrei Danaila <adanaila@codeaurora.org> Signed-off-by: Tony Truong <truong@codeaurora.org>
This commit is contained in:
parent
f688e16bf5
commit
39e32e5185
12 changed files with 83 additions and 16 deletions
|
@ -20,6 +20,7 @@ Required properties:
|
|||
- mhi-chan-cfg-#: mhi channel configuration parameters for platform
|
||||
- mhi-event-cfg-#: mhi event ring configuration parameters for platform
|
||||
- mhi-event-rings: number of event rings supported by platform
|
||||
- mhi-dev-address-win-size: size of the MHI device addressing window
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -36,4 +37,5 @@ Example:
|
|||
mhi-event-rings = <6>;
|
||||
mhi-chan-cfg-102 = <0x66 0x80 0x5 0x62>;
|
||||
mhi-event-cfg-0 = <0x80 0x0 0x0 0x11>;
|
||||
mhi-dev-address-win-size= <0x10 0x00000000>;
|
||||
};
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
mhi-event-cfg-2 = <0x80 0x2 0x5 0x11>;
|
||||
mhi-event-cfg-3 = <0x100 0x3 0x1 0x9>;
|
||||
mhi-event-cfg-4 = <0x100 0x4 0x1 0x8>;
|
||||
mhi-dev-address-win-size = <0x10 0x00000000>;
|
||||
};
|
||||
|
||||
&pm8994_mpps {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -441,8 +441,8 @@ struct mhi_dev_space {
|
|||
dma_addr_t dma_dev_mem_start;
|
||||
size_t dev_mem_len;
|
||||
struct mhi_ring_ctxt ring_ctxt;
|
||||
dma_addr_t start_win_addr;
|
||||
dma_addr_t end_win_addr;
|
||||
u64 start_win_addr;
|
||||
u64 end_win_addr;
|
||||
};
|
||||
|
||||
struct mhi_device_ctxt {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
@ -214,15 +215,54 @@ static int enable_bb_ctxt(struct mhi_ring *bb_ctxt, int nr_el)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void calculate_mhi_addressing_window(
|
||||
struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||
/*
|
||||
* The device can have severe addressing limitations, and in this case
|
||||
* the MHI driver may be restricted on where memory can be allocated.
|
||||
*
|
||||
* The allocation of the MHI control data structures takes place as one
|
||||
* big, physically contiguous allocation.
|
||||
* The device's addressing window, must be placed around that control segment
|
||||
* allocation.
|
||||
* Here we attempt to do this by building an addressing window around the
|
||||
* initial allocated control segment.
|
||||
*
|
||||
* The window size is specified by the device and must be contiguous,
|
||||
* but depending on where the control segment was allocated, it may be
|
||||
* necessary to leave more room, before the ctrl segment start or after
|
||||
* the ctrl segment end.
|
||||
* The following assumptions are made:
|
||||
* Assumption: 1. size of allocated ctrl seg << (device allocation window / 2)
|
||||
* 2. allocated ctrl seg is physically contiguous
|
||||
*/
|
||||
static int calculate_mhi_addressing_window(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||
{
|
||||
dma_addr_t dma_dev_mem_start;
|
||||
dma_addr_t dma_seg_size = 0x1FF00000UL;
|
||||
dma_addr_t dma_max_addr = (dma_addr_t)(-1);
|
||||
u64 dma_dev_mem_start = 0;
|
||||
u64 dma_seg_size = 0;
|
||||
u64 dma_max_addr = (dma_addr_t)(-1);
|
||||
u64 dev_address_limit = 0;
|
||||
int r = 0;
|
||||
const struct device_node *np =
|
||||
mhi_dev_ctxt->dev_info->plat_dev->dev.of_node;
|
||||
|
||||
dma_dev_mem_start = mhi_dev_ctxt->dev_space.dma_dev_mem_start;
|
||||
r = of_property_read_u64(np, "mhi-dev-address-win-size",
|
||||
&dev_address_limit);
|
||||
if (r) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to get device addressing limit ret %d",
|
||||
r);
|
||||
return r;
|
||||
}
|
||||
/* Mask off the last 3 bits for address calculation */
|
||||
dev_address_limit &= ~0x7;
|
||||
mhi_log(MHI_MSG_INFO, "Device Addressing limit 0x%llx\n",
|
||||
dev_address_limit);
|
||||
dma_seg_size = dev_address_limit / 2;
|
||||
|
||||
/*
|
||||
* The region of the allocated control segment is within the
|
||||
* first half of the device's addressing limit
|
||||
*/
|
||||
if (dma_dev_mem_start < dma_seg_size) {
|
||||
mhi_dev_ctxt->dev_space.start_win_addr = 0;
|
||||
mhi_dev_ctxt->dev_space.end_win_addr =
|
||||
|
@ -230,15 +270,26 @@ static void calculate_mhi_addressing_window(
|
|||
(dma_seg_size - dma_dev_mem_start);
|
||||
} else if (dma_dev_mem_start >= dma_seg_size &&
|
||||
dma_dev_mem_start <= (dma_max_addr - dma_seg_size)) {
|
||||
/*
|
||||
* The start of the control segment is located past
|
||||
* halfway point of the device's addressing limit
|
||||
* Place the control segment in the middle of the device's
|
||||
* addressing range
|
||||
*/
|
||||
mhi_dev_ctxt->dev_space.start_win_addr =
|
||||
dma_dev_mem_start - dma_seg_size;
|
||||
mhi_dev_ctxt->dev_space.end_win_addr =
|
||||
dma_dev_mem_start + dma_seg_size;
|
||||
} else if (dma_dev_mem_start > (dma_max_addr - dma_seg_size)) {
|
||||
mhi_dev_ctxt->dev_space.start_win_addr =
|
||||
dma_dev_mem_start - (dma_seg_size +
|
||||
(dma_seg_size - (dma_max_addr -
|
||||
dma_dev_mem_start)));
|
||||
/*
|
||||
* The start of the control segment is located at the tail end
|
||||
* of the host addressing space. Leave extra addressing space
|
||||
* at window start
|
||||
*/
|
||||
mhi_dev_ctxt->dev_space.start_win_addr = dma_dev_mem_start;
|
||||
mhi_dev_ctxt->dev_space.start_win_addr -=
|
||||
dma_seg_size + (dma_seg_size -
|
||||
(dma_max_addr - dma_dev_mem_start));
|
||||
mhi_dev_ctxt->dev_space.end_win_addr = dma_max_addr;
|
||||
}
|
||||
mhi_log(MHI_MSG_INFO,
|
||||
|
@ -246,7 +297,7 @@ static void calculate_mhi_addressing_window(
|
|||
(u64)dma_dev_mem_start,
|
||||
(u64)mhi_dev_ctxt->dev_space.start_win_addr,
|
||||
(u64)mhi_dev_ctxt->dev_space.end_win_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_mhi_dev_mem(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||
|
@ -274,7 +325,12 @@ int init_mhi_dev_mem(struct mhi_device_ctxt *mhi_dev_ctxt)
|
|||
dma_dev_mem_start = mhi_dev_ctxt->dev_space.dma_dev_mem_start;
|
||||
memset(dev_mem_start, 0, mhi_dev_ctxt->dev_space.dev_mem_len);
|
||||
|
||||
calculate_mhi_addressing_window(mhi_dev_ctxt);
|
||||
r = calculate_mhi_addressing_window(mhi_dev_ctxt);
|
||||
if (r) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to calculate addressing window ret %d", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
mhi_log(MHI_MSG_INFO, "Starting Seg address: virt 0x%p, dma 0x%llx\n",
|
||||
dev_mem_start, (u64)dma_dev_mem_start);
|
||||
|
@ -441,7 +497,7 @@ error_state_change_event_handle:
|
|||
kfree(mhi_dev_ctxt->mhi_ev_wq.state_change_event);
|
||||
error_event_handle_alloc:
|
||||
kfree(mhi_dev_ctxt->mhi_ev_wq.mhi_event_wq);
|
||||
return MHI_STATUS_ERROR;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int mhi_init_state_change_thread_work_queue(
|
||||
|
|
Loading…
Add table
Reference in a new issue