* [PATCH v7 09/15] ACPI: platform-msi: retrieve dev id from IORT
From: Hanjun Guo @ 2017-01-14 4:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113121144.GE20837@red-moon>
Hi Lorenzo,
On 2017/1/13 20:11, Lorenzo Pieralisi wrote:
> On Wed, Jan 11, 2017 at 11:06:33PM +0800, Hanjun Guo wrote:
>> For devices connecting to ITS, it needs dev id to identify itself, and
>> this dev id is represented in the IORT table in named component node
>> [1] for platform devices, so in this patch we will scan the IORT to
>> retrieve device's dev id.
>>
>> For named components we know that there are always two steps
>> involved (second optional):
>>
>> (1) Retrieve the initial id (this may well provide the final mapping)
>> (2) Map the id (optional if (1) represents the map type we need), this
>> is needed for use cases such as NC (named component) -> SMMU -> ITS
>> mappings.
>>
>> we have API iort_node_get_id() for step (1) above and
>> iort_node_map_rid() for step (2), so create a wrapper
>> iort_node_map_platform_id() to retrieve the dev id.
>>
>> [1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf
> This patch should be split and IORT changes should be squashed with
> patch 10.
If split the changes for IORT and its platform msi, API introduced in IORT will
not be used in a single patch, seems violate the suggestion of "new introduced API
needs to be used in the same patch", did I miss something?
>
>> Suggested-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Suggested-by: Tomasz Nowicki <tn@semihalf.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Sinan Kaya <okaya@codeaurora.org>
>> Cc: Tomasz Nowicki <tn@semihalf.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> ---
>> drivers/acpi/arm64/iort.c | 56 +++++++++++++++++++++++++++
>> drivers/irqchip/irq-gic-v3-its-platform-msi.c | 4 +-
>> include/linux/acpi_iort.h | 8 ++++
>> 3 files changed, 67 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 069a690..95fd20b 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -30,6 +30,7 @@
>> #define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP)
>> #define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \
>> (1 << ACPI_IORT_NODE_SMMU_V3))
>> +#define IORT_TYPE_ANY (IORT_MSI_TYPE | IORT_IOMMU_TYPE)
>>
>> struct iort_its_msi_chip {
>> struct list_head list;
>> @@ -406,6 +407,34 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
>> return NULL;
>> }
>>
>> +static
>> +struct acpi_iort_node *iort_node_map_platform_id(struct acpi_iort_node *node,
>> + u32 *id_out, u8 type_mask,
>> + int index)
>> +{
>> + struct acpi_iort_node *parent;
>> + u32 id;
>> +
>> + /* step 1: retrieve the initial dev id */
>> + parent = iort_node_get_id(node, &id, IORT_TYPE_ANY, index);
>> + if (!parent)
>> + return NULL;
>> +
>> + /*
>> + * optional step 2: map the initial dev id if its parent is not
>> + * the target type we wanted, map it again for the use cases such
>> + * as NC (named component) -> SMMU -> ITS. If the type is matched,
>> + * return the parent pointer directly.
>> + */
>> + if (!(IORT_TYPE_MASK(parent->type) & type_mask))
>> + parent = iort_node_map_id(parent, id, id_out, type_mask);
>> + else
>> + if (id_out)
> Remove this pointer check.
This was added because of NULL pointer reference, I passed NULL for id_out because I
only want to get its parent node, I think we have four options:
- Introduce a new API to get the parent only from the scratch, but it will duplicate the code
a lot;
- Don't check the id_out in iort_node_map_platform_id(), and introduce a wrapper and pass the
dummy id for iort_node_map_platform_id() :
static
struct acpi_iort_node *iort_node_get_platform_parent{struct device *dev, u8 type_mask}
{
struct acpi_iort_node *node, *parent = NULL;
int i;
u32 dummy_id;
node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
iort_match_node_callback, dev);
if (!node)
return NULL;
for (i = 0; i < node->mapping_count; i++) {
/* we just want to get the parent node */
parent = iort_node_map_platform_id(node, &dummy_id,
IORT_MSI_TYPE, i);
if (parent)
break;
}
return parent;
}
- Similar solution as above but don't introduce wrapper, just use dummy_id if
iort_node_map_platform_id() is called;
- Use the solution I proposed in this patch.
Please share you suggestion on this :)
>
>> + *id_out = id;
>> +
>> + return parent;
>> +}
>> +
>> static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
>> {
>> struct pci_bus *pbus;
>> @@ -444,6 +473,33 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
>> }
>>
>> /**
>> + * iort_pmsi_get_dev_id() - Get the device id for a device
>> + * @dev: The device for which the mapping is to be done.
>> + * @dev_id: The device ID found.
>> + *
>> + * Returns: 0 for successful find a dev id, errors otherwise
> Nit: -ENODEV on error
>
>> + */
>> +int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
>> +{
>> + int i;
>> + struct acpi_iort_node *node;
>> +
>> + if (!iort_table)
>> + return -ENODEV;
> I do not think this iort_table check is needed.
Agreed, it will be checked in iort_scan_node() and it's called
in iort_find_dev_node().
>
>> + node = iort_find_dev_node(dev);
>> + if (!node)
>> + return -ENODEV;
>> +
>> + for (i = 0; i < node->mapping_count; i++) {
>> + if(iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
> ^
>
> Nit: Missing a space.
I was on a flight when updating the patches, seems it's not a good place for coding :)
I will update the patch set when you are ok with the solutions I proposed, thank you
very much for the review.
Hanjun
^ permalink raw reply
* [PATCH v7 00/15] ACPI platform MSI support and its example mbigen
From: Hanjun Guo @ 2017-01-14 4:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5878E02E.5080602@hisilicon.com>
Hi Wei,
On 2017/1/13 22:11, Wei Xu wrote:
> Hi Hanjun,
>
> On 2017/1/11 15:06, Hanjun Guo wrote:
>> With platform msi support landed in the kernel, and the introduction
>> of IORT for GICv3 ITS (PCI MSI) and SMMU, the framework for platform msi
>> is ready, this patch set add few patches to enable the ACPI platform
>> msi support.
>>
>> For platform device connecting to ITS on arm platform, we have IORT
>> table with the named componant node to describe the mappings of paltform
>> device and ITS, so we can retrieve the dev id and find its parent
>> irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).
>>
>> v6 -> v7:
>> - Introduce iort_node_map_platform_id() to retrieve the
>> dev id for both NC (named component) -> ITS/SMMU and
>> NC -> SMMU -> ITS cases, suggested by Lorenzo;
>>
>> - Reorder the patches and rewrite some commit message;
>>
>> - Remove the test tags because it has major changes
>> to retrieve the dev id, Sinan, Majun, Xinwei, could
>> you please test them again on your platform?
>>
>> - rebased on top of 4.10-rc3 and Lorenzo's patch
>> https://patchwork.kernel.org/patch/9507041/
>>
>> - Tested against Agustin's patch [1-2/3] "[PATCH V9 0/3] irqchip: qcom:
>> Add IRQ combiner driver"
> I tested this patch set on the Hisilicon D05 board with these patches:
>
> [1] Agustin's V9 IRQ combiner driver patch set
> https://patchwork.kernel.org/patch/9474751/
>
> [2] Lorenzo's v2 iort_node_get_id fix patch
> https://patchwork.kernel.org/patch/9507041/
>
> The branch is at https://github.com/hisilicon/linux-hisi/tree/topic-acpi-mbigen.
>
> The integrated XGE, SAS and PCIe controller works fine.
> So with this patch set:
>
> Tested-by: Wei Xu <xuwei5@hisilicon.com>
I didn't test PCIe it's good to know it's working, thanks for testing
and let me know.
Hanjun
^ permalink raw reply
* [PATCH v6 0/3] dmaengine: xilinx_dma: Bug fixes
From: Kedareswara rao Appana @ 2017-01-14 5:35 UTC (permalink / raw)
To: linux-arm-kernel
This patch series fixes below bugs in DMA and VDMA IP's
---> Do not start VDMA until frame buffer is processed by the h/w
---> Fix bug in Multi frame sotres handling in VDMA
---> Fix issues w.r.to multi frame descriptors submit with AXI DMA S2MM(recv) Side.
Kedareswara rao Appana (3):
dmaengine: xilinx_dma: Check for channel idle state before submitting
dma descriptor
dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in
vdma
dmaengine: xilinx_dma: Fix race condition in the driver for multiple
descriptor scenario
.../devicetree/bindings/dma/xilinx/xilinx_dma.txt | 2 +
drivers/dma/xilinx/xilinx_dma.c | 270 ++++++++++++---------
2 files changed, 161 insertions(+), 111 deletions(-)
--
2.1.2
^ permalink raw reply
* [PATCH v6 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor
From: Kedareswara rao Appana @ 2017-01-14 5:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>
Add variable for checking channel idle state to ensure that dma descriptor is not
Submitted when DMA engine is in progress.
This will avoids the pollling for a bit in the status register to know
Dma state in the driver hot path.
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Updated commit message as suggested by Vinod.
---> Added Channel idle variable description in the driver
as suggested by Vinod.
Changes for v5:
---> None.
Changes for v4:
---> None.
Changes for v3:
---> None.
Changes for v2:
---> Add idle check in the reset as suggested by Jose Abreu
---> Removed xilinx_dma_is_running/xilinx_dma_is_idle checks
in the driver and used common idle checks across the driver
as suggested by Laurent Pinchart.
drivers/dma/xilinx/xilinx_dma.c | 61 +++++++++++++++--------------------------
1 file changed, 22 insertions(+), 39 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 8288fe4..5eeea57 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -321,6 +321,7 @@ struct xilinx_dma_tx_descriptor {
* @cyclic: Check for cyclic transfers.
* @genlock: Support genlock mode
* @err: Channel has errors
+ * @idle: Check for channel idle
* @tasklet: Cleanup work after irq
* @config: Device configuration info
* @flush_on_fsync: Flush on Frame sync
@@ -351,6 +352,7 @@ struct xilinx_dma_chan {
bool cyclic;
bool genlock;
bool err;
+ bool idle;
struct tasklet_struct tasklet;
struct xilinx_vdma_config config;
bool flush_on_fsync;
@@ -920,32 +922,6 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
}
/**
- * xilinx_dma_is_running - Check if DMA channel is running
- * @chan: Driver specific DMA channel
- *
- * Return: '1' if running, '0' if not.
- */
-static bool xilinx_dma_is_running(struct xilinx_dma_chan *chan)
-{
- return !(dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) &
- XILINX_DMA_DMASR_HALTED) &&
- (dma_ctrl_read(chan, XILINX_DMA_REG_DMACR) &
- XILINX_DMA_DMACR_RUNSTOP);
-}
-
-/**
- * xilinx_dma_is_idle - Check if DMA channel is idle
- * @chan: Driver specific DMA channel
- *
- * Return: '1' if idle, '0' if not.
- */
-static bool xilinx_dma_is_idle(struct xilinx_dma_chan *chan)
-{
- return dma_ctrl_read(chan, XILINX_DMA_REG_DMASR) &
- XILINX_DMA_DMASR_IDLE;
-}
-
-/**
* xilinx_dma_halt - Halt DMA channel
* @chan: Driver specific DMA channel
*/
@@ -966,6 +942,7 @@ static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR));
chan->err = true;
}
+ chan->idle = true;
}
/**
@@ -1007,6 +984,9 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
if (chan->err)
return;
+ if (!chan->idle)
+ return;
+
if (list_empty(&chan->pending_list))
return;
@@ -1018,13 +998,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
tail_segment = list_last_entry(&tail_desc->segments,
struct xilinx_vdma_tx_segment, node);
- /* If it is SG mode and hardware is busy, cannot submit */
- if (chan->has_sg && xilinx_dma_is_running(chan) &&
- !xilinx_dma_is_idle(chan)) {
- dev_dbg(chan->dev, "DMA controller still busy\n");
- return;
- }
-
/*
* If hardware is idle, then all descriptors on the running lists are
* done, start new transfers
@@ -1110,6 +1083,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
}
+ chan->idle = false;
if (!chan->has_sg) {
list_del(&desc->node);
list_add_tail(&desc->node, &chan->active_list);
@@ -1136,6 +1110,9 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
if (chan->err)
return;
+ if (!chan->idle)
+ return;
+
if (list_empty(&chan->pending_list))
return;
@@ -1181,6 +1158,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
list_splice_tail_init(&chan->pending_list, &chan->active_list);
chan->desc_pendingcount = 0;
+ chan->idle = false;
}
/**
@@ -1196,15 +1174,11 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
if (chan->err)
return;
- if (list_empty(&chan->pending_list))
+ if (!chan->idle)
return;
- /* If it is SG mode and hardware is busy, cannot submit */
- if (chan->has_sg && xilinx_dma_is_running(chan) &&
- !xilinx_dma_is_idle(chan)) {
- dev_dbg(chan->dev, "DMA controller still busy\n");
+ if (list_empty(&chan->pending_list))
return;
- }
head_desc = list_first_entry(&chan->pending_list,
struct xilinx_dma_tx_descriptor, node);
@@ -1302,6 +1276,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
list_splice_tail_init(&chan->pending_list, &chan->active_list);
chan->desc_pendingcount = 0;
+ chan->idle = false;
}
/**
@@ -1366,6 +1341,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
}
chan->err = false;
+ chan->idle = true;
return err;
}
@@ -1447,6 +1423,7 @@ static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
if (status & XILINX_DMA_DMASR_FRM_CNT_IRQ) {
spin_lock(&chan->lock);
xilinx_dma_complete_descriptor(chan);
+ chan->idle = true;
chan->start_transfer(chan);
spin_unlock(&chan->lock);
}
@@ -2327,6 +2304,12 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
chan->has_sg = xdev->has_sg;
chan->desc_pendingcount = 0x0;
chan->ext_addr = xdev->ext_addr;
+ /* This variable enusres that descripotrs are not
+ * Submited when dma engine is in progress. This variable is
+ * Added to avoid pollling for a bit in the status register to
+ * Know dma state in the driver hot path.
+ */
+ chan->idle = true;
spin_lock_init(&chan->lock);
INIT_LIST_HEAD(&chan->pending_list);
--
2.1.2
^ permalink raw reply related
* [PATCH v6 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
From: Kedareswara rao Appana @ 2017-01-14 5:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>
When VDMA is configured for more than one frame in the h/w.
For example h/w is configured for n number of frames, user
Submits n number of frames and triggered the DMA using issue_pending API.
In the current driver flow we are submitting one frame at a time,
But we should submit all the n number of frames at one time
As the h/w is configured for n number of frames.
This patch fixes this issue.
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Added Rob Acked-by
---> Updated commit message as suggested by Vinod.
Changes for v5:
---> Updated xlnx,fstore-config property to xlnx,fstore-enable
and updated description as suggested by Rob.
Changes for v4:
---> Add Check for framestore configuration on Transmit case as well
as suggested by Jose Abreu.
---> Modified the dev_dbg checks to dev_warn checks as suggested
by Jose Abreu.
Changes for v3:
---> Added Checks for frame store configuration. If frame store
Configuration is not present at the h/w level and user
Submits less frames added debug prints in the driver as relevant.
Changes for v2:
---> Fixed race conditions in the driver as suggested by Jose Abreu
---> Fixed unnecessray if else checks in the vdma_start_transfer
as suggested by Laurent Pinchart.
.../devicetree/bindings/dma/xilinx/xilinx_dma.txt | 2 +
drivers/dma/xilinx/xilinx_dma.c | 78 +++++++++++++++-------
2 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
index a2b8bfa..e951c09 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
@@ -66,6 +66,8 @@ Optional child node properties:
Optional child node properties for VDMA:
- xlnx,genlock-mode: Tells Genlock synchronization is
enabled/disabled in hardware.
+- xlnx,fstore-enable: boolean; if defined, it indicates that controller
+ supports frame store configuration.
Optional child node properties for AXI DMA:
-dma-channels: Number of dma channels in child node.
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 5eeea57..edb5b71 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -322,6 +322,7 @@ struct xilinx_dma_tx_descriptor {
* @genlock: Support genlock mode
* @err: Channel has errors
* @idle: Check for channel idle
+ * @has_fstoreen: Check for frame store configuration
* @tasklet: Cleanup work after irq
* @config: Device configuration info
* @flush_on_fsync: Flush on Frame sync
@@ -353,6 +354,7 @@ struct xilinx_dma_chan {
bool genlock;
bool err;
bool idle;
+ bool has_fstoreen;
struct tasklet_struct tasklet;
struct xilinx_vdma_config config;
bool flush_on_fsync;
@@ -990,6 +992,27 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
if (list_empty(&chan->pending_list))
return;
+ /*
+ * Note: When VDMA is built with default h/w configuration
+ * User should submit frames upto H/W configured.
+ * If users submits less than h/w configured
+ * VDMA engine tries to write to a invalid location
+ * Results undefined behaviour/memory corruption.
+ *
+ * If user would like to submit frames less than h/w capable
+ * On S2MM side please enable debug info 13 at the h/w level
+ * On MM2S side please enable debug info 6 at the h/w level
+ * It will allows the frame buffers numbers to be modified at runtime.
+ */
+ if (!chan->has_fstoreen &&
+ chan->desc_pendingcount < chan->num_frms) {
+ dev_warn(chan->dev, "Frame Store Configuration is not enabled at the\n");
+ dev_warn(chan->dev, "H/w level enable Debug info 13 or 6 at the h/w level\n");
+ dev_warn(chan->dev, "OR Submit the frames upto h/w Capable\n\r");
+
+ return;
+ }
+
desc = list_first_entry(&chan->pending_list,
struct xilinx_dma_tx_descriptor, node);
tail_desc = list_last_entry(&chan->pending_list,
@@ -1052,25 +1075,38 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
if (chan->has_sg) {
dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
tail_segment->phys);
+ list_splice_tail_init(&chan->pending_list, &chan->active_list);
+ chan->desc_pendingcount = 0;
} else {
struct xilinx_vdma_tx_segment *segment, *last = NULL;
- int i = 0;
+ int i = 0, j = 0;
if (chan->desc_submitcount < chan->num_frms)
i = chan->desc_submitcount;
- list_for_each_entry(segment, &desc->segments, node) {
- if (chan->ext_addr)
- vdma_desc_write_64(chan,
- XILINX_VDMA_REG_START_ADDRESS_64(i++),
- segment->hw.buf_addr,
- segment->hw.buf_addr_msb);
- else
- vdma_desc_write(chan,
- XILINX_VDMA_REG_START_ADDRESS(i++),
- segment->hw.buf_addr);
-
- last = segment;
+ for (j = 0; j < chan->num_frms; ) {
+ list_for_each_entry(segment, &desc->segments, node) {
+ if (chan->ext_addr)
+ vdma_desc_write_64(chan,
+ XILINX_VDMA_REG_START_ADDRESS_64(i++),
+ segment->hw.buf_addr,
+ segment->hw.buf_addr_msb);
+ else
+ vdma_desc_write(chan,
+ XILINX_VDMA_REG_START_ADDRESS(i++),
+ segment->hw.buf_addr);
+
+ last = segment;
+ }
+ list_del(&desc->node);
+ list_add_tail(&desc->node, &chan->active_list);
+ j++;
+ if (list_empty(&chan->pending_list) ||
+ (i == chan->num_frms))
+ break;
+ desc = list_first_entry(&chan->pending_list,
+ struct xilinx_dma_tx_descriptor,
+ node);
}
if (!last)
@@ -1081,20 +1117,14 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE,
last->hw.stride);
vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
- }
- chan->idle = false;
- if (!chan->has_sg) {
- list_del(&desc->node);
- list_add_tail(&desc->node, &chan->active_list);
- chan->desc_submitcount++;
- chan->desc_pendingcount--;
+ chan->desc_submitcount += j;
+ chan->desc_pendingcount -= j;
if (chan->desc_submitcount == chan->num_frms)
chan->desc_submitcount = 0;
- } else {
- list_splice_tail_init(&chan->pending_list, &chan->active_list);
- chan->desc_pendingcount = 0;
}
+
+ chan->idle = false;
}
/**
@@ -1342,6 +1372,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
chan->err = false;
chan->idle = true;
+ chan->desc_submitcount = 0;
return err;
}
@@ -2320,6 +2351,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
has_dre = of_property_read_bool(node, "xlnx,include-dre");
chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode");
+ chan->has_fstoreen = of_property_read_bool(node, "xlnx,fstore-enable");
err = of_property_read_u32(node, "xlnx,datawidth", &value);
if (err) {
--
2.1.2
^ permalink raw reply related
* [PATCH v6 3/3] dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario
From: Kedareswara rao Appana @ 2017-01-14 5:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484372155-19423-1-git-send-email-appanad@xilinx.com>
As per AXI DMA spec the software must not move the tail pointer to a location
That has not been updated (next descriptor field of the h/w descriptor
Should always point to a valid address).
When user submits multiple descriptors on the recv side, with the
Current driver flow the last buffer descriptor next descriptor field
Points to a invalid location, resulting the invalid data or errors in the
DMA engine.
This patch fixes this issue by creating a Buffer Descritpor Chain during
Channel allocation itself and use those Buffer Descriptors.
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v6:
---> Updated Commit message as suggested by Vinod.
Changes for v5:
---> None.
Changes for v4:
---> None.
Changes for v3:
---> None.
Changes for v2:
---> None.
drivers/dma/xilinx/xilinx_dma.c | 133 +++++++++++++++++++++++++---------------
1 file changed, 83 insertions(+), 50 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index edb5b71..c5cd935 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -163,6 +163,7 @@
#define XILINX_DMA_BD_SOP BIT(27)
#define XILINX_DMA_BD_EOP BIT(26)
#define XILINX_DMA_COALESCE_MAX 255
+#define XILINX_DMA_NUM_DESCS 255
#define XILINX_DMA_NUM_APP_WORDS 5
/* Multi-Channel DMA Descriptor offsets*/
@@ -310,6 +311,7 @@ struct xilinx_dma_tx_descriptor {
* @pending_list: Descriptors waiting
* @active_list: Descriptors ready to submit
* @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
* @common: DMA common channel
* @desc_pool: Descriptors pool
* @dev: The dma device
@@ -331,7 +333,9 @@ struct xilinx_dma_tx_descriptor {
* @desc_submitcount: Descriptor h/w submitted count
* @residue: Residue for AXI DMA
* @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
* @cyclic_seg_v: Statically allocated segment base for cyclic transfers
+ * @cyclic_seg_p: Physical allocated segments base for cyclic dma
* @start_transfer: Differentiate b/w DMA IP's transfer
*/
struct xilinx_dma_chan {
@@ -342,6 +346,7 @@ struct xilinx_dma_chan {
struct list_head pending_list;
struct list_head active_list;
struct list_head done_list;
+ struct list_head free_seg_list;
struct dma_chan common;
struct dma_pool *desc_pool;
struct device *dev;
@@ -363,7 +368,9 @@ struct xilinx_dma_chan {
u32 desc_submitcount;
u32 residue;
struct xilinx_axidma_tx_segment *seg_v;
+ dma_addr_t seg_p;
struct xilinx_axidma_tx_segment *cyclic_seg_v;
+ dma_addr_t cyclic_seg_p;
void (*start_transfer)(struct xilinx_dma_chan *chan);
u16 tdest;
};
@@ -569,17 +576,31 @@ static struct xilinx_axidma_tx_segment *
xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
{
struct xilinx_axidma_tx_segment *segment;
- dma_addr_t phys;
-
- segment = dma_pool_zalloc(chan->desc_pool, GFP_ATOMIC, &phys);
- if (!segment)
- return NULL;
+ unsigned long flags;
- segment->phys = phys;
+ spin_lock_irqsave(&chan->lock, flags);
+ if (!list_empty(&chan->free_seg_list)) {
+ segment = list_first_entry(&chan->free_seg_list,
+ struct xilinx_axidma_tx_segment,
+ node);
+ list_del(&segment->node);
+ }
+ spin_unlock_irqrestore(&chan->lock, flags);
return segment;
}
+static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
+{
+ u32 next_desc = hw->next_desc;
+ u32 next_desc_msb = hw->next_desc_msb;
+
+ memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
+
+ hw->next_desc = next_desc;
+ hw->next_desc_msb = next_desc_msb;
+}
+
/**
* xilinx_dma_free_tx_segment - Free transaction segment
* @chan: Driver specific DMA channel
@@ -588,7 +609,9 @@ xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
struct xilinx_axidma_tx_segment *segment)
{
- dma_pool_free(chan->desc_pool, segment, segment->phys);
+ xilinx_dma_clean_hw_desc(&segment->hw);
+
+ list_add_tail(&segment->node, &chan->free_seg_list);
}
/**
@@ -713,16 +736,26 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
{
struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+ unsigned long flags;
dev_dbg(chan->dev, "Free all channel resources.\n");
xilinx_dma_free_descriptors(chan);
+
if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
- xilinx_dma_free_tx_segment(chan, chan->cyclic_seg_v);
- xilinx_dma_free_tx_segment(chan, chan->seg_v);
+ spin_lock_irqsave(&chan->lock, flags);
+ INIT_LIST_HEAD(&chan->free_seg_list);
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ /* Free Memory that is allocated for cyclic DMA Mode */
+ dma_free_coherent(chan->dev, sizeof(*chan->cyclic_seg_v),
+ chan->cyclic_seg_v, chan->cyclic_seg_p);
+ }
+
+ if (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA) {
+ dma_pool_destroy(chan->desc_pool);
+ chan->desc_pool = NULL;
}
- dma_pool_destroy(chan->desc_pool);
- chan->desc_pool = NULL;
}
/**
@@ -805,6 +838,7 @@ static void xilinx_dma_do_tasklet(unsigned long data)
static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
{
struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+ int i;
/* Has this channel already been allocated? */
if (chan->desc_pool)
@@ -815,11 +849,30 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
* for meeting Xilinx VDMA specification requirement.
*/
if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
- chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool",
- chan->dev,
- sizeof(struct xilinx_axidma_tx_segment),
- __alignof__(struct xilinx_axidma_tx_segment),
- 0);
+ /* Allocate the buffer descriptors. */
+ chan->seg_v = dma_zalloc_coherent(chan->dev,
+ sizeof(*chan->seg_v) *
+ XILINX_DMA_NUM_DESCS,
+ &chan->seg_p, GFP_KERNEL);
+ if (!chan->seg_v) {
+ dev_err(chan->dev,
+ "unable to allocate channel %d descriptors\n",
+ chan->id);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+ chan->seg_v[i].hw.next_desc =
+ lower_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+ ((i + 1) % XILINX_DMA_NUM_DESCS));
+ chan->seg_v[i].hw.next_desc_msb =
+ upper_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+ ((i + 1) % XILINX_DMA_NUM_DESCS));
+ chan->seg_v[i].phys = chan->seg_p +
+ sizeof(*chan->seg_v) * i;
+ list_add_tail(&chan->seg_v[i].node,
+ &chan->free_seg_list);
+ }
} else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool",
chan->dev,
@@ -834,7 +887,8 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
0);
}
- if (!chan->desc_pool) {
+ if (!chan->desc_pool &&
+ (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA)) {
dev_err(chan->dev,
"unable to allocate channel %d descriptor pool\n",
chan->id);
@@ -843,22 +897,20 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
/*
- * For AXI DMA case after submitting a pending_list, keep
- * an extra segment allocated so that the "next descriptor"
- * pointer on the tail descriptor always points to a
- * valid descriptor, even when paused after reaching taildesc.
- * This way, it is possible to issue additional
- * transfers without halting and restarting the channel.
- */
- chan->seg_v = xilinx_axidma_alloc_tx_segment(chan);
-
- /*
* For cyclic DMA mode we need to program the tail Descriptor
* register with a value which is not a part of the BD chain
* so allocating a desc segment during channel allocation for
* programming tail descriptor.
*/
- chan->cyclic_seg_v = xilinx_axidma_alloc_tx_segment(chan);
+ chan->cyclic_seg_v = dma_zalloc_coherent(chan->dev,
+ sizeof(*chan->cyclic_seg_v),
+ &chan->cyclic_seg_p, GFP_KERNEL);
+ if (!chan->cyclic_seg_v) {
+ dev_err(chan->dev,
+ "unable to allocate desc segment for cyclic DMA\n");
+ return -ENOMEM;
+ }
+ chan->cyclic_seg_v->phys = chan->cyclic_seg_p;
}
dma_cookie_init(dchan);
@@ -1198,7 +1250,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
{
struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
- struct xilinx_axidma_tx_segment *tail_segment, *old_head, *new_head;
+ struct xilinx_axidma_tx_segment *tail_segment;
u32 reg;
if (chan->err)
@@ -1217,21 +1269,6 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
tail_segment = list_last_entry(&tail_desc->segments,
struct xilinx_axidma_tx_segment, node);
- if (chan->has_sg && !chan->xdev->mcdma) {
- old_head = list_first_entry(&head_desc->segments,
- struct xilinx_axidma_tx_segment, node);
- new_head = chan->seg_v;
- /* Copy Buffer Descriptor fields. */
- new_head->hw = old_head->hw;
-
- /* Swap and save new reserve */
- list_replace_init(&old_head->node, &new_head->node);
- chan->seg_v = old_head;
-
- tail_segment->hw.next_desc = chan->seg_v->phys;
- head_desc->async_tx.phys = new_head->phys;
- }
-
reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
@@ -1729,7 +1766,7 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
{
struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
struct xilinx_dma_tx_descriptor *desc;
- struct xilinx_axidma_tx_segment *segment = NULL, *prev = NULL;
+ struct xilinx_axidma_tx_segment *segment = NULL;
u32 *app_w = (u32 *)context;
struct scatterlist *sg;
size_t copy;
@@ -1780,10 +1817,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
XILINX_DMA_NUM_APP_WORDS);
}
- if (prev)
- prev->hw.next_desc = segment->phys;
-
- prev = segment;
sg_used += copy;
/*
@@ -1797,7 +1830,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
segment = list_first_entry(&desc->segments,
struct xilinx_axidma_tx_segment, node);
desc->async_tx.phys = segment->phys;
- prev->hw.next_desc = segment->phys;
/* For the last DMA_MEM_TO_DEV transfer, set EOP */
if (chan->direction == DMA_MEM_TO_DEV) {
@@ -2346,6 +2378,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
INIT_LIST_HEAD(&chan->pending_list);
INIT_LIST_HEAD(&chan->done_list);
INIT_LIST_HEAD(&chan->active_list);
+ INIT_LIST_HEAD(&chan->free_seg_list);
/* Retrieve the channel properties from the device tree */
has_dre = of_property_read_bool(node, "xlnx,include-dre");
--
2.1.2
^ permalink raw reply related
* [PATCH 05/62] watchdog: bcm2835_wdt: Convert to use device managed functions and other improvements
From: Eric Anholt @ 2017-01-14 6:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484091325-9199-6-git-send-email-linux@roeck-us.net>
Guenter Roeck <linux@roeck-us.net> writes:
> Use device managed functions to simplify error handling, reduce
> source code size, improve readability, and reduce the likelyhood of bugs.
> Other improvements as listed below.
>
> The conversion was done automatically with coccinelle using the
> following semantic patches. The semantic patches and the scripts used
> to generate this commit log are available at
> https://github.com/groeck/coccinelle-patches
>
> - Drop assignments to otherwise unused variables
> - Replace of_iomap() with platform_get_resource() followed by
> devm_ioremap_resource()
Every time I see this pattern I wish we had a
devm_ioremap_platform_resource().
> - Replace &pdev->dev with dev if 'struct device *dev' is a declared
> variable
> - Use devm_watchdog_register_driver() to register watchdog device
> - Replace shutdown function with call to watchdog_stop_on_reboot()
I'm trusting you here that this last change is right. All the rest of
it looks good:
Acked-by: Eric Anholt <eric@anholt.net>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170113/817a1030/attachment.sig>
^ permalink raw reply
* [PATCH v1 1/3] dt: bindings: add documentation for zx2967 family reset controller
From: Baoyou Xie @ 2017-01-14 7:05 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds dt-binding documentation for zx2967 family
reset controller.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
.../devicetree/bindings/reset/zte,zx2967-reset.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
diff --git a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
new file mode 100644
index 0000000..22d590e
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
@@ -0,0 +1,20 @@
+ZTE zx2967 SoCs Reset Controller
+=======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: should be one of the following.
+ * zte,zx296718-reset
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- #reset-cells: must be 1.
+
+example:
+
+ toprst: reset at 1461060 {
+ compatible = "zte,zx296718-reset";
+ reg = <0x01461060 0x8>;
+ #reset-cells = <1>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v1 2/3] MAINTAINERS: add zx2967 reset controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-14 7:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484377530-30635-1-git-send-email-baoyou.xie@linaro.org>
Add the zx2967 reset controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
MAINTAINERS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2793808..08f8155 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1980,10 +1980,12 @@ L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-zx/
F: drivers/clk/zte/
+F: drivers/reset/reset-zx2967.c
F: drivers/soc/zte/
F: drivers/thermal/zx*
F: Documentation/devicetree/bindings/arm/zte.txt
F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
+F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
F: Documentation/devicetree/bindings/soc/zte/
F: Documentation/devicetree/bindings/thermal/zx*
F: include/dt-bindings/soc/zx*.h
--
2.7.4
^ permalink raw reply related
* [PATCH v1 3/3] reset: zx2967: add reset controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-14 7:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484377530-30635-1-git-send-email-baoyou.xie@linaro.org>
This patch adds reset controller driver for ZTE's zx2967 family.
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
drivers/reset/Kconfig | 6 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-zx2967.c | 136 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 143 insertions(+)
create mode 100644 drivers/reset/reset-zx2967.c
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 172dc96..972d077 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -92,6 +92,12 @@ config RESET_ZYNQ
help
This enables the reset controller driver for Xilinx Zynq SoCs.
+config RESET_ZX2967
+ bool "ZX2967 Reset Driver"
+ depends on ARCH_ZX || COMPILE_TEST
+ help
+ This enables the reset controller driver for ZTE zx2967 family.
+
source "drivers/reset/sti/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
source "drivers/reset/tegra/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 13b346e..807b77b 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
+obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o
diff --git a/drivers/reset/reset-zx2967.c b/drivers/reset/reset-zx2967.c
new file mode 100644
index 0000000..63f9c41
--- /dev/null
+++ b/drivers/reset/reset-zx2967.c
@@ -0,0 +1,136 @@
+/*
+ * ZTE's zx2967 family thermal sensor driver
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+struct zx2967_reset {
+ void __iomem *reg_base;
+ spinlock_t lock;
+ struct reset_controller_dev rcdev;
+};
+
+static int zx2967_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct zx2967_reset *reset = NULL;
+ int bank = id / 32;
+ int offset = id % 32;
+ unsigned int reg;
+ unsigned long flags;
+
+ reset = container_of(rcdev, struct zx2967_reset, rcdev);
+
+ spin_lock_irqsave(&reset->lock, flags);
+
+ reg = readl(reset->reg_base + (bank * 4));
+ writel(reg & ~BIT(offset), reset->reg_base + (bank * 4));
+ reg = readl(reset->reg_base + (bank * 4));
+
+ spin_unlock_irqrestore(&reset->lock, flags);
+
+ return 0;
+}
+
+static int zx2967_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct zx2967_reset *reset = NULL;
+ int bank = id / 32;
+ int offset = id % 32;
+ unsigned int reg;
+ unsigned long flags;
+
+ reset = container_of(rcdev, struct zx2967_reset, rcdev);
+
+ spin_lock_irqsave(&reset->lock, flags);
+
+ reg = readl(reset->reg_base + (bank * 4));
+ writel(reg | BIT(offset), reset->reg_base + (bank * 4));
+ reg = readl(reset->reg_base + (bank * 4));
+
+ spin_unlock_irqrestore(&reset->lock, flags);
+
+ return 0;
+}
+
+static struct reset_control_ops zx2967_reset_ops = {
+ .assert = zx2967_reset_assert,
+ .deassert = zx2967_reset_deassert,
+};
+
+static int zx2967_reset_probe(struct platform_device *pdev)
+{
+ struct zx2967_reset *reset;
+ struct resource *res;
+
+ reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+ if (!reset)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reset->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(reset->reg_base))
+ return PTR_ERR(reset->reg_base);
+
+ spin_lock_init(&reset->lock);
+
+ reset->rcdev.owner = THIS_MODULE;
+ reset->rcdev.nr_resets = resource_size(res) * 8;
+ reset->rcdev.ops = &zx2967_reset_ops;
+ reset->rcdev.of_node = pdev->dev.of_node;
+
+ dev_info(&pdev->dev, "reset controller cnt:%d",
+ reset->rcdev.nr_resets);
+
+ return reset_controller_register(&reset->rcdev);
+}
+
+static int zx2967_reset_remove(struct platform_device *pdev)
+{
+ struct zx2967_reset *reset = platform_get_drvdata(pdev);
+
+ reset_controller_unregister(&reset->rcdev);
+
+ return 0;
+}
+
+static const struct of_device_id zx2967_reset_dt_ids[] = {
+ { .compatible = "zte,zx296718-reset", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, zx2967_reset_dt_ids);
+
+static struct platform_driver zx2967_reset_driver = {
+ .probe = zx2967_reset_probe,
+ .remove = zx2967_reset_remove,
+ .driver = {
+ .name = "zx2967-reset",
+ .of_match_table = zx2967_reset_dt_ids,
+ },
+};
+
+static int __init zx2967_reset_init(void)
+{
+ return platform_driver_register(&zx2967_reset_driver);
+}
+arch_initcall(zx2967_reset_init);
+
+static void __exit zx2967_reset_exit(void)
+{
+ platform_driver_unregister(&zx2967_reset_driver);
+}
+module_exit(zx2967_reset_exit);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
+MODULE_DESCRIPTION("ZTE zx2967 Reset Controller Driver");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCHv4 3/5] pinctrl: mvebu: pinctrl driver for 98DX3236 SoC
From: Chris Packham @ 2017-01-14 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2fca7ac2-9a88-19b1-28c5-5192b9c4a2bc@gmail.com>
On 13/01/17 22:54, Sebastian Hesselbarth wrote:
> On 13.01.2017 10:12, Chris Packham wrote:
>> From: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>>
>> This pinctrl driver supports the 98DX3236, 98DX3336 and 98DX4251 SoCs
>> from Marvell.
>>
>> Signed-off-by: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
>> ---
>>
>> Notes:
>> Changes in v2:
>> - include sdio support for the 98DX4251
>> Changes in v3:
>> - None
>> Changes in v4:
>> - Correct some discrepencies between binding and driver.
>
> Well, unfortunately I still see differences between the "gpio" in
> the binding and "gpo" in the driver.
>
> Please go back to that list I sent you yesterday and fix them all.
>
I think you may have missed my initial reply [1]. Or I have missed your
response to it. Long story short "gpo" is intentional because some of
those pins can't be used as inputs. But if you still want me to change
it I will.
[1] - https://lkml.org/lkml/2017/1/12/117
^ permalink raw reply
* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Boris Brezillon @ 2017-01-14 8:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0fafcd8d-cf99-de6b-728f-5e3637810b68@gmail.com>
On Fri, 13 Jan 2017 18:33:40 +0100
Marek Vasut <marek.vasut@gmail.com> wrote:
> On 01/13/2017 05:56 PM, Boris Brezillon wrote:
> > On Fri, 13 Jan 2017 17:44:12 +0100
> > Marek Vasut <marek.vasut@gmail.com> wrote:
> >
> >> On 01/13/2017 05:28 PM, Boris Brezillon wrote:
> >>> On Fri, 13 Jan 2017 17:13:55 +0100
> >>> Marek Vasut <marek.vasut@gmail.com> wrote:
> >>>
> >>>> On 01/13/2017 04:12 PM, Matthias Brugger wrote:
> >>>>>
> >>>>>
> >>>>> On 13/01/17 15:17, Boris Brezillon wrote:
> >>>>>> On Fri, 13 Jan 2017 15:13:29 +0800
> >>>>>> Guochun Mao <guochun.mao@mediatek.com> wrote:
> >>>>>>
> >>>>>>> Add Mediatek nor flash node.
> >>>>>>>
> >>>>>>> Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
> >>>>>>> ---
> >>>>>>> arch/arm/boot/dts/mt2701-evb.dts | 25 +++++++++++++++++++++++++
> >>>>>>> arch/arm/boot/dts/mt2701.dtsi | 12 ++++++++++++
> >>>>>>> 2 files changed, 37 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> b/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> index 082ca88..85e5ae8 100644
> >>>>>>> --- a/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> >>>>>>> @@ -24,6 +24,31 @@
> >>>>>>> };
> >>>>>>> };
> >>>>>>>
> >>>>>>> +&nor_flash {
> >>>>>>> + pinctrl-names = "default";
> >>>>>>> + pinctrl-0 = <&nor_pins_default>;
> >>>>>>> + status = "okay";
> >>>>>>> + flash at 0 {
> >>>>>>> + compatible = "jedec,spi-nor";
> >>>>>>> + reg = <0>;
> >>>>>>> + };
> >>>>>>> +};
> >>>>>>> +
> >>>>>>> +&pio {
> >>>>>>> + nor_pins_default: nor {
> >>>>>>> + pins1 {
> >>>>>>> + pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
> >>>>>>> + <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
> >>>>>>> + <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
> >>>>>>> + <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
> >>>>>>> + <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
> >>>>>>> + <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
> >>>>>>> + drive-strength = <MTK_DRIVE_4mA>;
> >>>>>>> + bias-pull-up;
> >>>>>>> + };
> >>>>>>> + };
> >>>>>>> +};
> >>>>>>> +
> >>>>>>> &uart0 {
> >>>>>>> status = "okay";
> >>>>>>> };
> >>>>>>> diff --git a/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> b/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> index bdf8954..1eefce4 100644
> >>>>>>> --- a/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> +++ b/arch/arm/boot/dts/mt2701.dtsi
> >>>>>>> @@ -227,6 +227,18 @@
> >>>>>>> status = "disabled";
> >>>>>>> };
> >>>>>>>
> >>>>>>> + nor_flash: spi at 11014000 {
> >>>>>>> + compatible = "mediatek,mt2701-nor",
> >>>>>>> + "mediatek,mt8173-nor";
> >>>>>>
> >>>>>> Why define both here? Is "mediatek,mt8173-nor" really providing a
> >>>>>> subset of the features supported by "mediatek,mt2701-nor"?
> >>>>>>
> >>>>>
> >>>>> I think even if the ip block is the same, we should provide both
> >>>>> bindings, just in case in the future we find out that mt2701 has some
> >>>>> hidden bug, feature or bug-feature. This way even if we update the
> >>>>> driver, we stay compatible with older device tree blobs in the wild.
> >>>>>
> >>>>> We can drop the mt2701-nor in the bindings definition if you want.
> >>>
> >>> Oh, sorry, I misunderstood. What I meant is that if you want to
> >>> list/support all possible compatibles, maybe you should just put one
> >>> compatible in your DT and patch your driver (+ binding doc) to define
> >>> all of them.
> >>
> >> Uh, what ? I lost you here :-)
I mean adding a new entry in the mtk_nor_of_ids table (in
mtk-quadspi.c) so that the mediatek,mt2701-nor compatible string can be
matched directly, and you won't need to define 2 compatible strings in
your device tree.
> >>
> >>>> This exactly. We should have a DT compat in the form:
> >>>> compatible = "vendor,<soc>-block", "vendor,<oldest-compat-soc>-block";
> >>>> Then if we find a problem in the future, we can match on the
> >>>> "vendor,<soc>-block" and still support the old DTs.
> >>>
> >>> Not sure it's only in term of whose IP appeared first. My understanding
> >>> is that it's a way to provide inheritance. For example:
> >>>
> >>> "<soc-vendor>,<ip-version>", "<ip-vendor>,<ip-version>";
> >>>
> >>> or
> >>>
> >>> "<soc-vendor>,<full-featured-ip-version>","<soc-vendor>,<basic-feature-ip-version>";
> >>>
> >>> BTW, which one is the oldest between mt8173 and mt2701? :-)
> >>
> >> And that's another thing and I agree with you, but I don't think that's
> >> what we're discussing in this thread. But (!), OT, I think we should
> >> codify the rules in Documentation/ . This discussion came up multiple
> >> times recently.
> >>
> >> And my question still stands, what do we put into the DT here, IMO
> >> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";
> >
> > I'd say
> >
> > compatible = "mediatek,mt8173-nor";
> >
> > because both compatible are referring to very specific IP version. It's
> > not the same as
>
> But then you don't have the ability to handle a block in this particular
> SoC in case there's a bug found in it in the future,
> so IMO it should be:
>
> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";
Sorry again, I meant
compatible = "mediatek,mt2701-nor";
>
> > compatible = "mediatek,mt8173-nor", "mediatek,mt81xx-nor";
>
> This doesn't look right, since here we add two new compatibles ...
That was just an example to describe how compatible inheritance works
(at least that's my understanding of it), it does not apply to this
particular use case.
>
> > where you clearly have a generic compatible which is overloaded by a
> > specific one.
> >
> > But anyway, I'm not the one taking the decision here, let's wait for DT
> > maintainers reviews.
> >
> >> and what goes into the binding document ? I guess both too ?
> >
> > If both exist, they should be both documented.
> >
>
>
^ permalink raw reply
* [PATCH v12 0/7] Enable PMUs in ACPI systems
From: Bamvor Zhang @ 2017-01-14 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484068672-15852-1-git-send-email-jeremy.linton@arm.com>
On Wed, Jan 11, 2017 at 1:17 AM, Jeremy Linton <jeremy.linton@arm.com> wrote:
> This patch expands and reworks the patches published by Mark Salter
> in order to clean up a few of the previous review comments, as well as
> add support for newer CPUs and big/little configurations.
Tests on D03 of huawei. Looks good to me.
Tested-by Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
^ permalink raw reply
* [PATCH] KVM: arm64: Increase number of memslots to 512
From: Linu Cherian @ 2017-01-14 9:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6fc30f74-d1ab-028f-7e5f-a5d1fe69c17a@arm.com>
> Let me be more precise. At the moment, KVM on arm64 doesn't support the
> delivery of MSIs generated by physical devices into a guest (patches are
> in progress, but not merged yet). So unless you used devices that have
> no need for interrupts, I don't see how this works.
>
> Can you shed some light on your test process?
>
We did the testing on top of latest VFIO msi support patches submitted
by Eric Auger.
^ permalink raw reply
* [PATCH v2 5/6] arm: dts: mt2701: Add ethernet device node.
From: John Crispin @ 2017-01-14 10:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484296978-18572-6-git-send-email-erin.lo@mediatek.com>
Hi Erin,
small comment inline
On 13/01/2017 09:42, Erin Lo wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Add ethernet device node for MT2701.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> ---
> arch/arm/boot/dts/mt2701-evb.dts | 40 ++++++++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/mt2701.dtsi | 22 ++++++++++++++++++++++
> 2 files changed, 62 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
> index a483798..40abd3b 100644
> --- a/arch/arm/boot/dts/mt2701-evb.dts
> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> @@ -28,7 +28,47 @@
> status = "okay";
> };
>
> +ð {
> + mac-address = [00 00 00 00 00 00];
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&gmac1_pins>;
> + gmac1: mac at 1 {
> + compatible = "mediatek,eth-mac";
> + reg = <1>;
> + phy-handle = <&phy5>;
> + };
> +
> + mdio-bus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + phy5: ethernet-phy at 5 {
> + reg = <5>;
> + phy-mode = "rgmii-rxid";
> + };
> + };
> +};
> +
> &pio {
> + gmac1_pins: eth at 0 {
> + pins_eth {
> + pinmux = <MT2701_PIN_275_MDC__FUNC_MDC>,
> + <MT2701_PIN_276_MDIO__FUNC_MDIO>,
> + <MT2701_PIN_262_G2_TXEN__FUNC_G2_TXEN>,
> + <MT2701_PIN_263_G2_TXD3__FUNC_G2_TXD3>,
> + <MT2701_PIN_264_G2_TXD2__FUNC_G2_TXD2>,
> + <MT2701_PIN_265_G2_TXD1__FUNC_G2_TXD1>,
> + <MT2701_PIN_266_G2_TXD0__FUNC_G2_TXD0>,
> + <MT2701_PIN_267_G2_TXC__FUNC_G2_TXC>,
> + <MT2701_PIN_268_G2_RXC__FUNC_G2_RXC>,
> + <MT2701_PIN_269_G2_RXD0__FUNC_G2_RXD0>,
> + <MT2701_PIN_270_G2_RXD1__FUNC_G2_RXD1>,
> + <MT2701_PIN_271_G2_RXD2__FUNC_G2_RXD2>,
> + <MT2701_PIN_272_G2_RXD3__FUNC_G2_RXD3>,
> + <MT2701_PIN_274_G2_RXDV__FUNC_G2_RXDV>;
> + };
> + };
> +
> spi_pins_a: spi0 at 0 {
> pins_spi {
> pinmux = <MT2701_PIN_53_SPI0_CSN__FUNC_SPI0_CS>,
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index 4f52019..3847f70 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -381,6 +381,28 @@
> #clock-cells = <1>;
> };
>
> + eth: ethernet at 1b100000 {
> + compatible = "mediatek,mt7623-eth";
> + reg = <0 0x1b100000 0 0x20000>;
> + interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>,
> + <GIC_SPI 199 IRQ_TYPE_LEVEL_LOW>,
> + <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
> + <&apmixedsys CLK_APMIXED_TRGPLL>,
> + <ðsys CLK_ETHSYS_ESW>,
> + <ðsys CLK_ETHSYS_GP2>,
> + <ðsys CLK_ETHSYS_GP1>;
> + clock-names = "ethif", "trgpll", "esw", "gp2", "gp1";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
> + resets = <&watchdog MT2701_TOPRGU_ETHDMA_RST>;
are you sure this is correct ? on mt7623 we point the reset at ethsys
and not the watchdog.
John
> + reset-names = "eth";
> + mediatek,ethsys = <ðsys>;
> + mediatek,pctl = <&syscfg_pctl_a>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + status = "disabled";
> + };
> +
> bdpsys: syscon at 1c000000 {
> compatible = "mediatek,mt2701-bdpsys", "syscon";
> reg = <0 0x1c000000 0 0x1000>;
>
^ permalink raw reply
* [PATCH] KVM: arm64: Increase number of memslots to 512
From: Marc Zyngier @ 2017-01-14 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGOz-0bR-YnUiv5v_duJYOQE3jxCoGRO=f05==tD5kL489g2CQ@mail.gmail.com>
On Sat, Jan 14 2017 at 09:53:52 AM, Linu Cherian <linucherian@gmail.com> wrote:
>> Let me be more precise. At the moment, KVM on arm64 doesn't support the
>> delivery of MSIs generated by physical devices into a guest (patches are
>> in progress, but not merged yet). So unless you used devices that have
>> no need for interrupts, I don't see how this works.
>>
>> Can you shed some light on your test process?
>>
>
> We did the testing on top of latest VFIO msi support patches submitted
> by Eric Auger.
Did you? That's reassuring. It would have been good if any of the Cavium
folks did chime in on the list and help reviewing though - so far, all
I've heard is a deafening silence. I guess there was no hurry for Cavium
to see these patches being merged.
Thanks,
M.
--
Jazz is not dead. It just smells funny.
^ permalink raw reply
* [PATCH] clk: rockchip: rk3288: make aclk_vio1_niu a critical clock
From: Heiko Stuebner @ 2017-01-14 11:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484097992-9118-1-git-send-email-jacob-chen@iotwrt.com>
Hi Jacob,
Am Mittwoch, 11. Januar 2017, 09:26:32 CET schrieb Jacob Chen:
> According to the pd blocks, VIO1_NIU is required by RGA,ISP and VOP1.
> Then at least one VIO_NIU should be turned on to supply eDP, HDMI, MIPI.
>
> If eDP,HDMI,MIPI is inited early than VOP or RGA is inited early than VOP1,
> system will hang.
>
> So make aclk_vio1_niu a critical clock and turn it on at all times.
NIU clocks are part of the interconnect, which we do not model at all yet,
so I guess all of those should never be turned off (until an interconnect
driver handles them).
Could you just make all of them critical in one go please, so that we don't
have to each clock on its own once things break?
Thanks
Heiko
>
> Signed-off-by: Jacob Chen <jacob-chen@iotwrt.com>
> ---
> drivers/clk/rockchip/clk-rk3288.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/clk/rockchip/clk-rk3288.c
> b/drivers/clk/rockchip/clk-rk3288.c index f071c24..59ee244 100644
> --- a/drivers/clk/rockchip/clk-rk3288.c
> +++ b/drivers/clk/rockchip/clk-rk3288.c
> @@ -815,6 +815,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[]
> __initdata = { static const char *const rk3288_critical_clocks[]
> __initconst = { "aclk_cpu",
> "aclk_peri",
> + "aclk_vio1_niu",
> "hclk_peri",
> "pclk_pd_pmu",
> };
^ permalink raw reply
* [PATCH v18 00/15] acpi, clocksource: add GTDT driver and GTDT support in arm_arch_timer
From: Fu Wei @ 2017-01-14 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113192920.GF2472@leverpostej>
Hi Mark,
On 14 January 2017 at 03:29, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> On Fri, Dec 09, 2016 at 01:33:04AM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> This patchset:
>> (1)Preparation for adding GTDT support in arm_arch_timer:
>> 1. Move some enums and marcos to header file;
>> 2. Add a new enum for spi type;
>> 3. Improve printk relevant code;
>> 4. Rename some enums and defines;
>> 5. Rework PPI determination;
>> 6. Rework counter frequency detection;
>> 7. Refactor arch_timer_needs_probing, move it into DT init call
>> 8. Introduce some new structs and refactor the MMIO timer init code
>> for reusing some common code.
>>
>> (2)Introduce ACPI GTDT parser: drivers/acpi/arm64/acpi_gtdt.c
>> Parse all kinds of timer in GTDT table of ACPI:arch timer,
>> memory-mapped timer and SBSA Generic Watchdog timer.
>> This driver can help to simplify all the relevant timer drivers,
>> and separate all the ACPI GTDT knowledge from them.
>>
>> (3)Simplify ACPI code for arm_arch_timer
>>
>> (4)Add GTDT support for ARM memory-mapped timer.
>>
>> This patchset has been tested on the following platforms with ACPI enabled:
>> (1)ARM Foundation v8 model
>
> Once v4.10-rc4 comes out this weekend, could you please rebase and
> repost this?
Yes, of course.
I have rebased v19 to the latest v4.10-rc3-e96f8f1, it dosen't need
any modification.
I will rebase it every day, and will repost it if it need any modification.
But for now, V19 works well with the master branch of upstream kernel.
Do I need to re-post it even if it doesn't need any improvement or
modification? :-)
>
> Marc and I will be happy to take a look then.
Great thanks for your help!
>
> Thanks,
> Mark.
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH 0/4] Drop drivers for Exynos4415
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Support for Exynos4415 is being removed because:
1. There are no upstream users,
2. There are no known downstream users,
3. Except compile testing, you cannot build working kernel
for Exynos4415 anymore.
Patches are rebased on current next and are independent.
Please pick up as you wish.
Best regards,
Krzysztof
Krzysztof Kozlowski (4):
ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
pinctrl: samsung: Remove support for Exynos4415 (SoC not supported
anymore)
drm: exynos: Remove support for Exynos4415 (SoC not supported anymore)
.../devicetree/bindings/clock/exynos4415-clock.txt | 38 -
.../bindings/display/exynos/exynos_dsim.txt | 1 -
.../bindings/display/exynos/samsung-fimd.txt | 1 -
arch/arm/mach-exynos/Kconfig | 5 -
arch/arm/mach-exynos/exynos.c | 1 -
arch/arm/mach-exynos/suspend.c | 1 -
drivers/clk/samsung/Makefile | 1 -
drivers/clk/samsung/clk-exynos4415.c | 1022 --------------------
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 15 +-
drivers/gpu/drm/exynos/exynos_drm_fimd.c | 18 +-
drivers/pinctrl/samsung/pinctrl-exynos.c | 75 --
drivers/pinctrl/samsung/pinctrl-samsung.c | 2 -
drivers/pinctrl/samsung/pinctrl-samsung.h | 1 -
include/dt-bindings/clock/exynos4415.h | 360 -------
14 files changed, 3 insertions(+), 1538 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
delete mode 100644 include/dt-bindings/clock/exynos4415.h
--
2.9.3
^ permalink raw reply
* [PATCH 1/4] ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>
Support for Exynos4415 is going away because there are no internal nor
external users.
Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the mach code.
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
arch/arm/mach-exynos/Kconfig | 5 -----
arch/arm/mach-exynos/exynos.c | 1 -
arch/arm/mach-exynos/suspend.c | 1 -
3 files changed, 7 deletions(-)
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 0bb63b8d21e7..0a99140b6ba2 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -95,11 +95,6 @@ config SOC_EXYNOS4412
default y
depends on ARCH_EXYNOS4
-config SOC_EXYNOS4415
- bool "SAMSUNG EXYNOS4415"
- default y
- depends on ARCH_EXYNOS4
-
config SOC_EXYNOS5250
bool "SAMSUNG EXYNOS5250"
default y
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 35b832f4bc7e..c404c15ad07f 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -210,7 +210,6 @@ static char const *const exynos_dt_compat[] __initconst = {
"samsung,exynos4210",
"samsung,exynos4212",
"samsung,exynos4412",
- "samsung,exynos4415",
"samsung,exynos5",
"samsung,exynos5250",
"samsung,exynos5260",
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index 518420241062..25e7c5326259 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -270,7 +270,6 @@ EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
-EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
--
2.9.3
^ permalink raw reply related
* [PATCH 2/4] clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>
Support for Exynos4415 is going away because there are no internal nor
external users.
Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the drivers.
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
.../devicetree/bindings/clock/exynos4415-clock.txt | 38 -
drivers/clk/samsung/Makefile | 1 -
drivers/clk/samsung/clk-exynos4415.c | 1022 --------------------
include/dt-bindings/clock/exynos4415.h | 360 -------
4 files changed, 1421 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
delete mode 100644 include/dt-bindings/clock/exynos4415.h
diff --git a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt b/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
deleted file mode 100644
index 847d98bae8cf..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Samsung Exynos4415 Clock Controller
-
-The Exynos4415 clock controller generates and supplies clock to various
-consumer devices within the Exynos4415 SoC.
-
-Required properties:
-
-- compatible: should be one of the following:
- - "samsung,exynos4415-cmu" - for the main system clocks controller
- (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains).
- - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory
- Controller (DMC) domain clock controller.
-
-- reg: physical base address of the controller and length of memory mapped
- region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos4415.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
- cmu: clock-controller at 10030000 {
- compatible = "samsung,exynos4415-cmu";
- reg = <0x10030000 0x18000>;
- #clock-cells = <1>;
- };
-
- cmu-dmc: clock-controller at 105C0000 {
- compatible = "samsung,exynos4415-cmu-dmc";
- reg = <0x105C0000 0x3000>;
- #clock-cells = <1>;
- };
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 57f4dc6dc447..7afc21dc374e 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o
obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
-obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c
deleted file mode 100644
index 6c9063159717..000000000000
--- a/drivers/clk/samsung/clk-exynos4415.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Common Clock Framework support for Exynos4415 SoC.
- */
-
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
-
-#include <dt-bindings/clock/exynos4415.h>
-
-#include "clk.h"
-#include "clk-pll.h"
-
-#define SRC_LEFTBUS 0x4200
-#define DIV_LEFTBUS 0x4500
-#define GATE_IP_LEFTBUS 0x4800
-#define GATE_IP_IMAGE 0x4930
-#define SRC_RIGHTBUS 0x8200
-#define DIV_RIGHTBUS 0x8500
-#define GATE_IP_RIGHTBUS 0x8800
-#define GATE_IP_PERIR 0x8960
-#define EPLL_LOCK 0xc010
-#define G3D_PLL_LOCK 0xc020
-#define DISP_PLL_LOCK 0xc030
-#define ISP_PLL_LOCK 0xc040
-#define EPLL_CON0 0xc110
-#define EPLL_CON1 0xc114
-#define EPLL_CON2 0xc118
-#define G3D_PLL_CON0 0xc120
-#define G3D_PLL_CON1 0xc124
-#define G3D_PLL_CON2 0xc128
-#define ISP_PLL_CON0 0xc130
-#define ISP_PLL_CON1 0xc134
-#define ISP_PLL_CON2 0xc138
-#define DISP_PLL_CON0 0xc140
-#define DISP_PLL_CON1 0xc144
-#define DISP_PLL_CON2 0xc148
-#define SRC_TOP0 0xc210
-#define SRC_TOP1 0xc214
-#define SRC_CAM 0xc220
-#define SRC_TV 0xc224
-#define SRC_MFC 0xc228
-#define SRC_G3D 0xc22c
-#define SRC_LCD 0xc234
-#define SRC_ISP 0xc238
-#define SRC_MAUDIO 0xc23c
-#define SRC_FSYS 0xc240
-#define SRC_PERIL0 0xc250
-#define SRC_PERIL1 0xc254
-#define SRC_CAM1 0xc258
-#define SRC_TOP_ISP0 0xc25c
-#define SRC_TOP_ISP1 0xc260
-#define SRC_MASK_TOP 0xc310
-#define SRC_MASK_CAM 0xc320
-#define SRC_MASK_TV 0xc324
-#define SRC_MASK_LCD 0xc334
-#define SRC_MASK_ISP 0xc338
-#define SRC_MASK_MAUDIO 0xc33c
-#define SRC_MASK_FSYS 0xc340
-#define SRC_MASK_PERIL0 0xc350
-#define SRC_MASK_PERIL1 0xc354
-#define DIV_TOP 0xc510
-#define DIV_CAM 0xc520
-#define DIV_TV 0xc524
-#define DIV_MFC 0xc528
-#define DIV_G3D 0xc52c
-#define DIV_LCD 0xc534
-#define DIV_ISP 0xc538
-#define DIV_MAUDIO 0xc53c
-#define DIV_FSYS0 0xc540
-#define DIV_FSYS1 0xc544
-#define DIV_FSYS2 0xc548
-#define DIV_PERIL0 0xc550
-#define DIV_PERIL1 0xc554
-#define DIV_PERIL2 0xc558
-#define DIV_PERIL3 0xc55c
-#define DIV_PERIL4 0xc560
-#define DIV_PERIL5 0xc564
-#define DIV_CAM1 0xc568
-#define DIV_TOP_ISP1 0xc56c
-#define DIV_TOP_ISP0 0xc570
-#define CLKDIV2_RATIO 0xc580
-#define GATE_SCLK_CAM 0xc820
-#define GATE_SCLK_TV 0xc824
-#define GATE_SCLK_MFC 0xc828
-#define GATE_SCLK_G3D 0xc82c
-#define GATE_SCLK_LCD 0xc834
-#define GATE_SCLK_MAUDIO 0xc83c
-#define GATE_SCLK_FSYS 0xc840
-#define GATE_SCLK_PERIL 0xc850
-#define GATE_IP_CAM 0xc920
-#define GATE_IP_TV 0xc924
-#define GATE_IP_MFC 0xc928
-#define GATE_IP_G3D 0xc92c
-#define GATE_IP_LCD 0xc934
-#define GATE_IP_FSYS 0xc940
-#define GATE_IP_PERIL 0xc950
-#define GATE_BLOCK 0xc970
-#define APLL_LOCK 0x14000
-#define APLL_CON0 0x14100
-#define SRC_CPU 0x14200
-#define DIV_CPU0 0x14500
-#define DIV_CPU1 0x14504
-
-static const unsigned long exynos4415_cmu_clk_regs[] __initconst = {
- SRC_LEFTBUS,
- DIV_LEFTBUS,
- GATE_IP_LEFTBUS,
- GATE_IP_IMAGE,
- SRC_RIGHTBUS,
- DIV_RIGHTBUS,
- GATE_IP_RIGHTBUS,
- GATE_IP_PERIR,
- EPLL_LOCK,
- G3D_PLL_LOCK,
- DISP_PLL_LOCK,
- ISP_PLL_LOCK,
- EPLL_CON0,
- EPLL_CON1,
- EPLL_CON2,
- G3D_PLL_CON0,
- G3D_PLL_CON1,
- G3D_PLL_CON2,
- ISP_PLL_CON0,
- ISP_PLL_CON1,
- ISP_PLL_CON2,
- DISP_PLL_CON0,
- DISP_PLL_CON1,
- DISP_PLL_CON2,
- SRC_TOP0,
- SRC_TOP1,
- SRC_CAM,
- SRC_TV,
- SRC_MFC,
- SRC_G3D,
- SRC_LCD,
- SRC_ISP,
- SRC_MAUDIO,
- SRC_FSYS,
- SRC_PERIL0,
- SRC_PERIL1,
- SRC_CAM1,
- SRC_TOP_ISP0,
- SRC_TOP_ISP1,
- SRC_MASK_TOP,
- SRC_MASK_CAM,
- SRC_MASK_TV,
- SRC_MASK_LCD,
- SRC_MASK_ISP,
- SRC_MASK_MAUDIO,
- SRC_MASK_FSYS,
- SRC_MASK_PERIL0,
- SRC_MASK_PERIL1,
- DIV_TOP,
- DIV_CAM,
- DIV_TV,
- DIV_MFC,
- DIV_G3D,
- DIV_LCD,
- DIV_ISP,
- DIV_MAUDIO,
- DIV_FSYS0,
- DIV_FSYS1,
- DIV_FSYS2,
- DIV_PERIL0,
- DIV_PERIL1,
- DIV_PERIL2,
- DIV_PERIL3,
- DIV_PERIL4,
- DIV_PERIL5,
- DIV_CAM1,
- DIV_TOP_ISP1,
- DIV_TOP_ISP0,
- CLKDIV2_RATIO,
- GATE_SCLK_CAM,
- GATE_SCLK_TV,
- GATE_SCLK_MFC,
- GATE_SCLK_G3D,
- GATE_SCLK_LCD,
- GATE_SCLK_MAUDIO,
- GATE_SCLK_FSYS,
- GATE_SCLK_PERIL,
- GATE_IP_CAM,
- GATE_IP_TV,
- GATE_IP_MFC,
- GATE_IP_G3D,
- GATE_IP_LCD,
- GATE_IP_FSYS,
- GATE_IP_PERIL,
- GATE_BLOCK,
- APLL_LOCK,
- APLL_CON0,
- SRC_CPU,
- DIV_CPU0,
- DIV_CPU1,
-};
-
-/* list of all parent clock list */
-PNAME(mout_g3d_pllsrc_p) = { "fin_pll", };
-
-PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
-PNAME(mout_g3d_pll_p) = { "fin_pll", "fout_g3d_pll", };
-PNAME(mout_isp_pll_p) = { "fin_pll", "fout_isp_pll", };
-PNAME(mout_disp_pll_p) = { "fin_pll", "fout_disp_pll", };
-
-PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", };
-PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
-PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", };
-PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", };
-
-PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", };
-PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_g3d_pll", };
-
-PNAME(mout_gdl_p) = { "mout_mpll_user_l", };
-PNAME(mout_gdr_p) = { "mout_mpll_user_r", };
-
-PNAME(mout_aclk_266_p) = { "mout_mpll_user_t", "mout_g3d_pll", };
-
-PNAME(group_epll_g3dpll_p) = { "mout_epll", "mout_g3d_pll" };
-PNAME(group_sclk_p) = { "xxti", "xusbxti",
- "none", "mout_isp_pll",
- "none", "none", "div_mpll_pre",
- "mout_epll", "mout_g3d_pll", };
-PNAME(group_spdif_p) = { "mout_audio0", "mout_audio1",
- "mout_audio2", "spdif_extclk", };
-PNAME(group_sclk_audio2_p) = { "audiocdclk2", "none",
- "none", "mout_isp_pll",
- "mout_disp_pll", "xusbxti",
- "div_mpll_pre", "mout_epll",
- "mout_g3d_pll", };
-PNAME(group_sclk_audio1_p) = { "audiocdclk1", "none",
- "none", "mout_isp_pll",
- "mout_disp_pll", "xusbxti",
- "div_mpll_pre", "mout_epll",
- "mout_g3d_pll", };
-PNAME(group_sclk_audio0_p) = { "audiocdclk0", "none",
- "none", "mout_isp_pll",
- "mout_disp_pll", "xusbxti",
- "div_mpll_pre", "mout_epll",
- "mout_g3d_pll", };
-PNAME(group_fimc_lclk_p) = { "xxti", "xusbxti",
- "none", "mout_isp_pll",
- "none", "mout_disp_pll",
- "mout_mpll_user_t", "mout_epll",
- "mout_g3d_pll", };
-PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti",
- "m_bitclkhsdiv4_4l", "mout_isp_pll",
- "mout_disp_pll", "sclk_hdmiphy",
- "div_mpll_pre", "mout_epll",
- "mout_g3d_pll", };
-PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy" };
-PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" };
-PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" };
-PNAME(mout_jpeg_p) = { "mout_jpeg_0", "mout_jpeg_1" };
-PNAME(mout_jpeg1_p) = { "mout_epll", "mout_g3d_pll" };
-PNAME(group_aclk_isp0_300_p) = { "mout_isp_pll", "div_mpll_pre" };
-PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" };
-PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" };
-PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" };
-PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" };
-
-static const struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initconst = {
- /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */
- FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
-};
-
-static const struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initconst = {
- FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000),
-};
-
-static const struct samsung_mux_clock exynos4415_mux_clks[] __initconst = {
- /*
- * NOTE: Following table is sorted by register address in ascending
- * order and then bitfield shift in descending order, as it is done
- * in the User's Manual. When adding new entries, please make sure
- * that the order is preserved, to avoid merge conflicts and make
- * further work with defined data easier.
- */
-
- /* SRC_LEFTBUS */
- MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p,
- SRC_LEFTBUS, 4, 1),
- MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1),
-
- /* SRC_RIGHTBUS */
- MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p,
- SRC_RIGHTBUS, 4, 1),
- MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1),
-
- /* SRC_TOP0 */
- MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1),
- MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p,
- SRC_TOP0, 24, 1),
- MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p,
- SRC_TOP0, 20, 1),
- MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p,
- SRC_TOP0, 16, 1),
- MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p,
- SRC_TOP0, 12, 1),
- MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
- SRC_TOP0, 8, 1),
- MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1),
- MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1),
-
- /* SRC_TOP1 */
- MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p,
- SRC_TOP1, 28, 1),
- MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p,
- SRC_TOP1, 16, 1),
- MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p,
- SRC_TOP1, 12, 1),
- MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp",
- group_mout_mpll_user_t_p, SRC_TOP1, 8, 1),
- MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p,
- SRC_TOP1, 0, 1),
-
- /* SRC_CAM */
- MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4),
- MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4),
- MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4),
- MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM,
- 12, 4),
- MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM,
- 8, 4),
- MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM,
- 4, 4),
- MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM,
- 0, 4),
-
- /* SRC_TV */
- MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
-
- /* SRC_MFC */
- MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
- MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1),
- MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0,
- 1),
-
- /* SRC_G3D */
- MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1),
- MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1),
- MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0,
- 1),
-
- /* SRC_LCD */
- MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4),
- MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4),
-
- /* SRC_ISP */
- MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP,
- 16, 4),
- MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP,
- 12, 4),
- MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP,
- 8, 4),
- MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP,
- 4, 4),
- MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP,
- 0, 4),
-
- /* SRC_MAUDIO */
- MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO,
- 0, 4),
-
- /* SRC_FSYS */
- MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
- MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
- MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
- MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
-
- /* SRC_PERIL0 */
- MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4),
- MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
- MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
- MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
-
- /* SRC_PERIL1 */
- MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4),
- MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4),
- MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4),
- MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4),
- MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1,
- 4, 4),
- MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1,
- 0, 4),
-
- /* SRC_CPU */
- MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p,
- SRC_CPU, 24, 1),
- MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1),
- MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0,
- CLK_MUX_READ_ONLY),
- MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
- CLK_SET_RATE_PARENT, 0),
-
- /* SRC_CAM1 */
- MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1",
- group_fimc_lclk_p, SRC_CAM1, 20, 1),
- MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0",
- group_fimc_lclk_p, SRC_CAM1, 16, 1),
- MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1),
- MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1),
- MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1,
- 0, 1),
-
- /* SRC_TOP_ISP0 */
- MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300",
- group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1),
- MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user",
- group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1),
- MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user",
- group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1),
-
- /* SRC_TOP_ISP1 */
- MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300",
- group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1),
- MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user",
- group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1),
-};
-
-static const struct samsung_div_clock exynos4415_div_clks[] __initconst = {
- /*
- * NOTE: Following table is sorted by register address in ascending
- * order and then bitfield shift in descending order, as it is done
- * in the User's Manual. When adding new entries, please make sure
- * that the order is preserved, to avoid merge conflicts and make
- * further work with defined data easier.
- */
-
- /* DIV_LEFTBUS */
- DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
- DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4),
-
- /* DIV_RIGHTBUS */
- DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
- DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4),
-
- /* DIV_TOP */
- DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp",
- "mout_aclk_400_mcuisp", DIV_TOP, 24, 3),
- DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3),
- DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3),
- DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3),
- DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4),
- DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3),
-
- /* DIV_CAM */
- DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4),
- DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4),
- DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4),
- DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM,
- 12, 4),
- DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM,
- 8, 4),
- DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM,
- 4, 4),
- DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM,
- 0, 4),
-
- /* DIV_TV */
- DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4),
-
- /* DIV_MFC */
- DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4),
-
- /* DIV_G3D */
- DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4),
-
- /* DIV_LCD */
- DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4),
- DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4),
-
- /* DIV_ISP */
- DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4),
- DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp",
- DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4),
- DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp",
- DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4),
- DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4),
-
- /* DIV_MAUDIO */
- DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8),
- DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4),
-
- /* DIV_FSYS0 */
- DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4),
-
- /* DIV_FSYS1 */
- DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
- DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
-
- /* DIV_FSYS2 */
- DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4,
- CLK_SET_RATE_PARENT, 0),
-
- /* DIV_PERIL0 */
- DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
- DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
- DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
- DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
-
- /* DIV_PERIL1 */
- DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
- DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
-
- /* DIV_PERIL2 */
- DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8,
- CLK_SET_RATE_PARENT, 0),
- DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
-
- /* DIV_PERIL4 */
- DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8),
- DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
- DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8),
- DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
-
- /* DIV_PERIL5 */
- DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6),
-
- /* DIV_CAM1 */
- DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc",
- "mout_pxlasync_csis1", DIV_CAM1, 24, 4),
- DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc",
- "mout_pxlasync_csis0", DIV_CAM1, 20, 4),
- DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4),
-
- /* DIV_CPU0 */
- DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3),
- DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3,
- CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
- DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3),
- DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3),
- DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3),
- DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
- DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
- DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3,
- CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
-
- /* DIV_CPU1 */
- DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
- DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
-};
-
-static const struct samsung_gate_clock exynos4415_gate_clks[] __initconst = {
- /*
- * NOTE: Following table is sorted by register address in ascending
- * order and then bitfield shift in descending order, as it is done
- * in the User's Manual. When adding new entries, please make sure
- * that the order is preserved, to avoid merge conflicts and make
- * further work with defined data easier.
- */
-
- /* GATE_IP_LEFTBUS */
- GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0,
- CLK_IGNORE_UNUSED, 0),
-
- /* GATE_IP_IMAGE */
- GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE,
- 9, 0, 0),
- GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE,
- 8, 0, 0),
- GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE,
- 7, 0, 0),
- GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE,
- 5, 0, 0),
- GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE,
- 4, 0, 0),
- GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0),
- GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0),
-
- /* GATE_IP_RIGHTBUS */
- GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100",
- GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100",
- GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100",
- GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100",
- GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100",
- GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100",
- GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100",
- GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100",
- GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0),
-
- /* GATE_IP_PERIR */
- GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100",
- GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100",
- GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100",
- GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100",
- GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100",
- GATE_IP_PERIR, 17, 0, 0),
- GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0),
- GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0),
- GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0),
- GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0),
- GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0,
- CLK_IGNORE_UNUSED, 0),
-
- /* GATE_SCLK_CAM - non-completed */
- GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc",
- "div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11,
- CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc",
- "div_pxlasync_csis0_fimc", GATE_SCLK_CAM,
- 10, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg",
- GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1",
- GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0",
- GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1",
- GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk",
- GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk",
- GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk",
- GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk",
- GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_TV */
- GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk",
- GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
- GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk",
- GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_MFC */
- GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc",
- GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_G3D */
- GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d",
- GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_LCD */
- GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0",
- GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre",
- GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0",
- GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0",
- GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_MAUDIO */
- GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0",
- GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0",
- GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_FSYS */
- GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre",
- GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
- GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
- GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
- GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
- GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_SCLK_PERIL */
- GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1",
- GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2",
- GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1",
- GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2",
- GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1",
- GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
- GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre",
- GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre",
- GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
- GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
- GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
- GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
- GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
- GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0),
-
- /* GATE_IP_CAM */
- GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM,
- 22, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM,
- 20, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM,
- 18, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM,
- 17, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM,
- 16, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0),
- GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0),
- GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0),
- GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0),
- GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0),
- GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0),
- GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0),
- GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0),
- GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0),
- GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0),
- GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0),
- GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0),
-
- /* GATE_IP_TV */
- GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0),
- GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0),
- GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0),
- GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0),
- GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0),
-
- /* GATE_IP_MFC */
- GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0),
- GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0),
- GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0),
-
- /* GATE_IP_G3D */
- GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0),
-
- /* GATE_IP_LCD */
- GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0),
- GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0),
- GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0),
- GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0),
- GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0),
-
- /* GATE_IP_FSYS */
- GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0),
- GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17,
- CLK_IGNORE_UNUSED, 0),
- GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0),
- GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13,
- 0, 0),
- GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
- GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
- GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
- GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
- GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
- GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
- GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0),
-
- /* GATE_IP_PERIL */
- GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0),
- GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0),
- GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0),
- GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0),
- GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0),
- GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0),
- GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0),
- GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0),
- GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0),
- GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0),
- GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0),
- GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0),
- GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0),
- GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0),
- GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
- GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
- GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
- GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0),
- GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
- GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
- GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
-};
-
-/*
- * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL
- */
-static const struct samsung_pll_rate_table exynos4415_pll_rates[] __initconst = {
- PLL_35XX_RATE(1600000000, 400, 3, 1),
- PLL_35XX_RATE(1500000000, 250, 2, 1),
- PLL_35XX_RATE(1400000000, 175, 3, 0),
- PLL_35XX_RATE(1300000000, 325, 3, 1),
- PLL_35XX_RATE(1200000000, 400, 4, 1),
- PLL_35XX_RATE(1100000000, 275, 3, 1),
- PLL_35XX_RATE(1066000000, 533, 6, 1),
- PLL_35XX_RATE(1000000000, 250, 3, 1),
- PLL_35XX_RATE(960000000, 320, 4, 1),
- PLL_35XX_RATE(900000000, 300, 4, 1),
- PLL_35XX_RATE(850000000, 425, 6, 1),
- PLL_35XX_RATE(800000000, 200, 3, 1),
- PLL_35XX_RATE(700000000, 175, 3, 1),
- PLL_35XX_RATE(667000000, 667, 12, 1),
- PLL_35XX_RATE(600000000, 400, 4, 2),
- PLL_35XX_RATE(550000000, 275, 3, 2),
- PLL_35XX_RATE(533000000, 533, 6, 2),
- PLL_35XX_RATE(520000000, 260, 3, 2),
- PLL_35XX_RATE(500000000, 250, 3, 2),
- PLL_35XX_RATE(440000000, 220, 3, 2),
- PLL_35XX_RATE(400000000, 200, 3, 2),
- PLL_35XX_RATE(350000000, 175, 3, 2),
- PLL_35XX_RATE(300000000, 300, 3, 3),
- PLL_35XX_RATE(266000000, 266, 3, 3),
- PLL_35XX_RATE(200000000, 200, 3, 3),
- PLL_35XX_RATE(160000000, 160, 3, 3),
- PLL_35XX_RATE(100000000, 200, 3, 4),
- { /* sentinel */ }
-};
-
-/* EPLL */
-static const struct samsung_pll_rate_table exynos4415_epll_rates[] __initconst = {
- PLL_36XX_RATE(800000000, 200, 3, 1, 0),
- PLL_36XX_RATE(288000000, 96, 2, 2, 0),
- PLL_36XX_RATE(192000000, 128, 2, 3, 0),
- PLL_36XX_RATE(144000000, 96, 2, 3, 0),
- PLL_36XX_RATE(96000000, 128, 2, 4, 0),
- PLL_36XX_RATE(84000000, 112, 2, 4, 0),
- PLL_36XX_RATE(80750011, 107, 2, 4, 43691),
- PLL_36XX_RATE(73728004, 98, 2, 4, 19923),
- PLL_36XX_RATE(67987602, 271, 3, 5, 62285),
- PLL_36XX_RATE(65911004, 175, 2, 5, 49982),
- PLL_36XX_RATE(50000000, 200, 3, 5, 0),
- PLL_36XX_RATE(49152003, 131, 2, 5, 4719),
- PLL_36XX_RATE(48000000, 128, 2, 5, 0),
- PLL_36XX_RATE(45250000, 181, 3, 5, 0),
- { /* sentinel */ }
-};
-
-static const struct samsung_pll_clock exynos4415_plls[] __initconst = {
- PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
- APLL_LOCK, APLL_CON0, exynos4415_pll_rates),
- PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
- EPLL_LOCK, EPLL_CON0, exynos4415_epll_rates),
- PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "mout_g3d_pllsrc",
- G3D_PLL_LOCK, G3D_PLL_CON0, exynos4415_pll_rates),
- PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
- ISP_PLL_LOCK, ISP_PLL_CON0, exynos4415_pll_rates),
- PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
- "fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, exynos4415_pll_rates),
-};
-
-static const struct samsung_cmu_info cmu_info __initconst = {
- .pll_clks = exynos4415_plls,
- .nr_pll_clks = ARRAY_SIZE(exynos4415_plls),
- .mux_clks = exynos4415_mux_clks,
- .nr_mux_clks = ARRAY_SIZE(exynos4415_mux_clks),
- .div_clks = exynos4415_div_clks,
- .nr_div_clks = ARRAY_SIZE(exynos4415_div_clks),
- .gate_clks = exynos4415_gate_clks,
- .nr_gate_clks = ARRAY_SIZE(exynos4415_gate_clks),
- .fixed_clks = exynos4415_fixed_rate_clks,
- .nr_fixed_clks = ARRAY_SIZE(exynos4415_fixed_rate_clks),
- .fixed_factor_clks = exynos4415_fixed_factor_clks,
- .nr_fixed_factor_clks = ARRAY_SIZE(exynos4415_fixed_factor_clks),
- .nr_clk_ids = CLK_NR_CLKS,
- .clk_regs = exynos4415_cmu_clk_regs,
- .nr_clk_regs = ARRAY_SIZE(exynos4415_cmu_clk_regs),
-};
-
-static void __init exynos4415_cmu_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &cmu_info);
-}
-CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
-
-/*
- * CMU DMC
- */
-
-#define MPLL_LOCK 0x008
-#define MPLL_CON0 0x108
-#define MPLL_CON1 0x10c
-#define MPLL_CON2 0x110
-#define BPLL_LOCK 0x118
-#define BPLL_CON0 0x218
-#define BPLL_CON1 0x21c
-#define BPLL_CON2 0x220
-#define SRC_DMC 0x300
-#define DIV_DMC1 0x504
-
-static const unsigned long exynos4415_cmu_dmc_clk_regs[] __initconst = {
- MPLL_LOCK,
- MPLL_CON0,
- MPLL_CON1,
- MPLL_CON2,
- BPLL_LOCK,
- BPLL_CON0,
- BPLL_CON1,
- BPLL_CON2,
- SRC_DMC,
- DIV_DMC1,
-};
-
-PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
-PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", };
-PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", };
-
-static const struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initconst = {
- MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1),
- MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1),
- MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1),
- MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1),
-};
-
-static const struct samsung_div_clock exynos4415_dmc_div_clks[] __initconst = {
- DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3),
- DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3),
- DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus",
- DIV_DMC1, 19, 2),
- DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3),
- DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
- DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
-};
-
-static const struct samsung_pll_clock exynos4415_dmc_plls[] __initconst = {
- PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
- MPLL_LOCK, MPLL_CON0, exynos4415_pll_rates),
- PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
- BPLL_LOCK, BPLL_CON0, exynos4415_pll_rates),
-};
-
-static const struct samsung_cmu_info cmu_dmc_info __initconst = {
- .pll_clks = exynos4415_dmc_plls,
- .nr_pll_clks = ARRAY_SIZE(exynos4415_dmc_plls),
- .mux_clks = exynos4415_dmc_mux_clks,
- .nr_mux_clks = ARRAY_SIZE(exynos4415_dmc_mux_clks),
- .div_clks = exynos4415_dmc_div_clks,
- .nr_div_clks = ARRAY_SIZE(exynos4415_dmc_div_clks),
- .nr_clk_ids = NR_CLKS_DMC,
- .clk_regs = exynos4415_cmu_dmc_clk_regs,
- .nr_clk_regs = ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs),
-};
-
-static void __init exynos4415_cmu_dmc_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &cmu_dmc_info);
-}
-CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
- exynos4415_cmu_dmc_init);
diff --git a/include/dt-bindings/clock/exynos4415.h b/include/dt-bindings/clock/exynos4415.h
deleted file mode 100644
index 7eed55100721..000000000000
--- a/include/dt-bindings/clock/exynos4415.h
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Device Tree binding constants for Samsung Exynos4415 clock controllers.
- */
-
-#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
-#define _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
-
-/*
- * Let each exported clock get a unique index, which is used on DT-enabled
- * platforms to lookup the clock from a clock specifier. These indices are
- * therefore considered an ABI and so must not be changed. This implies
- * that new clocks should be added either in free spaces between clock groups
- * or at the end.
- */
-
-/*
- * Main CMU
- */
-
-#define CLK_OSCSEL 1
-#define CLK_FIN_PLL 2
-#define CLK_FOUT_APLL 3
-#define CLK_FOUT_MPLL 4
-#define CLK_FOUT_EPLL 5
-#define CLK_FOUT_G3D_PLL 6
-#define CLK_FOUT_ISP_PLL 7
-#define CLK_FOUT_DISP_PLL 8
-
-/* Muxes */
-#define CLK_MOUT_MPLL_USER_L 16
-#define CLK_MOUT_GDL 17
-#define CLK_MOUT_MPLL_USER_R 18
-#define CLK_MOUT_GDR 19
-#define CLK_MOUT_EBI 20
-#define CLK_MOUT_ACLK_200 21
-#define CLK_MOUT_ACLK_160 22
-#define CLK_MOUT_ACLK_100 23
-#define CLK_MOUT_ACLK_266 24
-#define CLK_MOUT_G3D_PLL 25
-#define CLK_MOUT_EPLL 26
-#define CLK_MOUT_EBI_1 27
-#define CLK_MOUT_ISP_PLL 28
-#define CLK_MOUT_DISP_PLL 29
-#define CLK_MOUT_MPLL_USER_T 30
-#define CLK_MOUT_ACLK_400_MCUISP 31
-#define CLK_MOUT_G3D_PLLSRC 32
-#define CLK_MOUT_CSIS1 33
-#define CLK_MOUT_CSIS0 34
-#define CLK_MOUT_CAM1 35
-#define CLK_MOUT_FIMC3_LCLK 36
-#define CLK_MOUT_FIMC2_LCLK 37
-#define CLK_MOUT_FIMC1_LCLK 38
-#define CLK_MOUT_FIMC0_LCLK 39
-#define CLK_MOUT_MFC 40
-#define CLK_MOUT_MFC_1 41
-#define CLK_MOUT_MFC_0 42
-#define CLK_MOUT_G3D 43
-#define CLK_MOUT_G3D_1 44
-#define CLK_MOUT_G3D_0 45
-#define CLK_MOUT_MIPI0 46
-#define CLK_MOUT_FIMD0 47
-#define CLK_MOUT_TSADC_ISP 48
-#define CLK_MOUT_UART_ISP 49
-#define CLK_MOUT_SPI1_ISP 50
-#define CLK_MOUT_SPI0_ISP 51
-#define CLK_MOUT_PWM_ISP 52
-#define CLK_MOUT_AUDIO0 53
-#define CLK_MOUT_TSADC 54
-#define CLK_MOUT_MMC2 55
-#define CLK_MOUT_MMC1 56
-#define CLK_MOUT_MMC0 57
-#define CLK_MOUT_UART3 58
-#define CLK_MOUT_UART2 59
-#define CLK_MOUT_UART1 60
-#define CLK_MOUT_UART0 61
-#define CLK_MOUT_SPI2 62
-#define CLK_MOUT_SPI1 63
-#define CLK_MOUT_SPI0 64
-#define CLK_MOUT_SPDIF 65
-#define CLK_MOUT_AUDIO2 66
-#define CLK_MOUT_AUDIO1 67
-#define CLK_MOUT_MPLL_USER_C 68
-#define CLK_MOUT_HPM 69
-#define CLK_MOUT_CORE 70
-#define CLK_MOUT_APLL 71
-#define CLK_MOUT_PXLASYNC_CSIS1_FIMC 72
-#define CLK_MOUT_PXLASYNC_CSIS0_FIMC 73
-#define CLK_MOUT_JPEG 74
-#define CLK_MOUT_JPEG1 75
-#define CLK_MOUT_JPEG0 76
-#define CLK_MOUT_ACLK_ISP0_300 77
-#define CLK_MOUT_ACLK_ISP0_400 78
-#define CLK_MOUT_ACLK_ISP0_300_USER 79
-#define CLK_MOUT_ACLK_ISP1_300 80
-#define CLK_MOUT_ACLK_ISP1_300_USER 81
-#define CLK_MOUT_HDMI 82
-
-/* Dividers */
-#define CLK_DIV_GPL 90
-#define CLK_DIV_GDL 91
-#define CLK_DIV_GPR 92
-#define CLK_DIV_GDR 93
-#define CLK_DIV_ACLK_400_MCUISP 94
-#define CLK_DIV_EBI 95
-#define CLK_DIV_ACLK_200 96
-#define CLK_DIV_ACLK_160 97
-#define CLK_DIV_ACLK_100 98
-#define CLK_DIV_ACLK_266 99
-#define CLK_DIV_CSIS1 100
-#define CLK_DIV_CSIS0 101
-#define CLK_DIV_CAM1 102
-#define CLK_DIV_FIMC3_LCLK 103
-#define CLK_DIV_FIMC2_LCLK 104
-#define CLK_DIV_FIMC1_LCLK 105
-#define CLK_DIV_FIMC0_LCLK 106
-#define CLK_DIV_TV_BLK 107
-#define CLK_DIV_MFC 108
-#define CLK_DIV_G3D 109
-#define CLK_DIV_MIPI0_PRE 110
-#define CLK_DIV_MIPI0 111
-#define CLK_DIV_FIMD0 112
-#define CLK_DIV_UART_ISP 113
-#define CLK_DIV_SPI1_ISP_PRE 114
-#define CLK_DIV_SPI1_ISP 115
-#define CLK_DIV_SPI0_ISP_PRE 116
-#define CLK_DIV_SPI0_ISP 117
-#define CLK_DIV_PWM_ISP 118
-#define CLK_DIV_PCM0 119
-#define CLK_DIV_AUDIO0 120
-#define CLK_DIV_TSADC_PRE 121
-#define CLK_DIV_TSADC 122
-#define CLK_DIV_MMC1_PRE 123
-#define CLK_DIV_MMC1 124
-#define CLK_DIV_MMC0_PRE 125
-#define CLK_DIV_MMC0 126
-#define CLK_DIV_MMC2_PRE 127
-#define CLK_DIV_MMC2 128
-#define CLK_DIV_UART3 129
-#define CLK_DIV_UART2 130
-#define CLK_DIV_UART1 131
-#define CLK_DIV_UART0 132
-#define CLK_DIV_SPI1_PRE 133
-#define CLK_DIV_SPI1 134
-#define CLK_DIV_SPI0_PRE 135
-#define CLK_DIV_SPI0 136
-#define CLK_DIV_SPI2_PRE 137
-#define CLK_DIV_SPI2 138
-#define CLK_DIV_PCM2 139
-#define CLK_DIV_AUDIO2 140
-#define CLK_DIV_PCM1 141
-#define CLK_DIV_AUDIO1 142
-#define CLK_DIV_I2S1 143
-#define CLK_DIV_PXLASYNC_CSIS1_FIMC 144
-#define CLK_DIV_PXLASYNC_CSIS0_FIMC 145
-#define CLK_DIV_JPEG 146
-#define CLK_DIV_CORE2 147
-#define CLK_DIV_APLL 148
-#define CLK_DIV_PCLK_DBG 149
-#define CLK_DIV_ATB 150
-#define CLK_DIV_PERIPH 151
-#define CLK_DIV_COREM1 152
-#define CLK_DIV_COREM0 153
-#define CLK_DIV_CORE 154
-#define CLK_DIV_HPM 155
-#define CLK_DIV_COPY 156
-
-/* Gates */
-#define CLK_ASYNC_G3D 180
-#define CLK_ASYNC_MFCL 181
-#define CLK_ASYNC_TVX 182
-#define CLK_PPMULEFT 183
-#define CLK_GPIO_LEFT 184
-#define CLK_PPMUIMAGE 185
-#define CLK_QEMDMA2 186
-#define CLK_QEROTATOR 187
-#define CLK_SMMUMDMA2 188
-#define CLK_SMMUROTATOR 189
-#define CLK_MDMA2 190
-#define CLK_ROTATOR 191
-#define CLK_ASYNC_ISPMX 192
-#define CLK_ASYNC_MAUDIOX 193
-#define CLK_ASYNC_MFCR 194
-#define CLK_ASYNC_FSYSD 195
-#define CLK_ASYNC_LCD0X 196
-#define CLK_ASYNC_CAMX 197
-#define CLK_PPMURIGHT 198
-#define CLK_GPIO_RIGHT 199
-#define CLK_ANTIRBK_APBIF 200
-#define CLK_EFUSE_WRITER_APBIF 201
-#define CLK_MONOCNT 202
-#define CLK_TZPC6 203
-#define CLK_PROVISIONKEY1 204
-#define CLK_PROVISIONKEY0 205
-#define CLK_CMU_ISPPART 206
-#define CLK_TMU_APBIF 207
-#define CLK_KEYIF 208
-#define CLK_RTC 209
-#define CLK_WDT 210
-#define CLK_MCT 211
-#define CLK_SECKEY 212
-#define CLK_HDMI_CEC 213
-#define CLK_TZPC5 214
-#define CLK_TZPC4 215
-#define CLK_TZPC3 216
-#define CLK_TZPC2 217
-#define CLK_TZPC1 218
-#define CLK_TZPC0 219
-#define CLK_CMU_COREPART 220
-#define CLK_CMU_TOPPART 221
-#define CLK_PMU_APBIF 222
-#define CLK_SYSREG 223
-#define CLK_CHIP_ID 224
-#define CLK_SMMUFIMC_LITE2 225
-#define CLK_FIMC_LITE2 226
-#define CLK_PIXELASYNCM1 227
-#define CLK_PIXELASYNCM0 228
-#define CLK_PPMUCAMIF 229
-#define CLK_SMMUJPEG 230
-#define CLK_SMMUFIMC3 231
-#define CLK_SMMUFIMC2 232
-#define CLK_SMMUFIMC1 233
-#define CLK_SMMUFIMC0 234
-#define CLK_JPEG 235
-#define CLK_CSIS1 236
-#define CLK_CSIS0 237
-#define CLK_FIMC3 238
-#define CLK_FIMC2 239
-#define CLK_FIMC1 240
-#define CLK_FIMC0 241
-#define CLK_PPMUTV 242
-#define CLK_SMMUTV 243
-#define CLK_HDMI 244
-#define CLK_MIXER 245
-#define CLK_VP 246
-#define CLK_PPMUMFC_R 247
-#define CLK_PPMUMFC_L 248
-#define CLK_SMMUMFC_R 249
-#define CLK_SMMUMFC_L 250
-#define CLK_MFC 251
-#define CLK_PPMUG3D 252
-#define CLK_G3D 253
-#define CLK_PPMULCD0 254
-#define CLK_SMMUFIMD0 255
-#define CLK_DSIM0 256
-#define CLK_SMIES 257
-#define CLK_MIE0 258
-#define CLK_FIMD0 259
-#define CLK_TSADC 260
-#define CLK_PPMUFILE 261
-#define CLK_NFCON 262
-#define CLK_USBDEVICE 263
-#define CLK_USBHOST 264
-#define CLK_SROMC 265
-#define CLK_SDMMC2 266
-#define CLK_SDMMC1 267
-#define CLK_SDMMC0 268
-#define CLK_PDMA1 269
-#define CLK_PDMA0 270
-#define CLK_SPDIF 271
-#define CLK_PWM 272
-#define CLK_PCM2 273
-#define CLK_PCM1 274
-#define CLK_I2S1 275
-#define CLK_SPI2 276
-#define CLK_SPI1 277
-#define CLK_SPI0 278
-#define CLK_I2CHDMI 279
-#define CLK_I2C7 280
-#define CLK_I2C6 281
-#define CLK_I2C5 282
-#define CLK_I2C4 283
-#define CLK_I2C3 284
-#define CLK_I2C2 285
-#define CLK_I2C1 286
-#define CLK_I2C0 287
-#define CLK_UART3 288
-#define CLK_UART2 289
-#define CLK_UART1 290
-#define CLK_UART0 291
-
-/* Special clocks */
-#define CLK_SCLK_PXLAYSNC_CSIS1_FIMC 330
-#define CLK_SCLK_PXLAYSNC_CSIS0_FIMC 331
-#define CLK_SCLK_JPEG 332
-#define CLK_SCLK_CSIS1 333
-#define CLK_SCLK_CSIS0 334
-#define CLK_SCLK_CAM1 335
-#define CLK_SCLK_FIMC3_LCLK 336
-#define CLK_SCLK_FIMC2_LCLK 337
-#define CLK_SCLK_FIMC1_LCLK 338
-#define CLK_SCLK_FIMC0_LCLK 339
-#define CLK_SCLK_PIXEL 340
-#define CLK_SCLK_HDMI 341
-#define CLK_SCLK_MIXER 342
-#define CLK_SCLK_MFC 343
-#define CLK_SCLK_G3D 344
-#define CLK_SCLK_MIPIDPHY4L 345
-#define CLK_SCLK_MIPI0 346
-#define CLK_SCLK_MDNIE0 347
-#define CLK_SCLK_FIMD0 348
-#define CLK_SCLK_PCM0 349
-#define CLK_SCLK_AUDIO0 350
-#define CLK_SCLK_TSADC 351
-#define CLK_SCLK_EBI 352
-#define CLK_SCLK_MMC2 353
-#define CLK_SCLK_MMC1 354
-#define CLK_SCLK_MMC0 355
-#define CLK_SCLK_I2S 356
-#define CLK_SCLK_PCM2 357
-#define CLK_SCLK_PCM1 358
-#define CLK_SCLK_AUDIO2 359
-#define CLK_SCLK_AUDIO1 360
-#define CLK_SCLK_SPDIF 361
-#define CLK_SCLK_SPI2 362
-#define CLK_SCLK_SPI1 363
-#define CLK_SCLK_SPI0 364
-#define CLK_SCLK_UART3 365
-#define CLK_SCLK_UART2 366
-#define CLK_SCLK_UART1 367
-#define CLK_SCLK_UART0 368
-#define CLK_SCLK_HDMIPHY 369
-
-/*
- * Total number of clocks of main CMU.
- * NOTE: Must be equal to last clock ID increased by one.
- */
-#define CLK_NR_CLKS 370
-
-/*
- * CMU DMC
- */
-#define CLK_DMC_FOUT_MPLL 1
-#define CLK_DMC_FOUT_BPLL 2
-
-#define CLK_DMC_MOUT_MPLL 3
-#define CLK_DMC_MOUT_BPLL 4
-#define CLK_DMC_MOUT_DPHY 5
-#define CLK_DMC_MOUT_DMC_BUS 6
-
-#define CLK_DMC_DIV_DMC 7
-#define CLK_DMC_DIV_DPHY 8
-#define CLK_DMC_DIV_DMC_PRE 9
-#define CLK_DMC_DIV_DMCP 10
-#define CLK_DMC_DIV_DMCD 11
-#define CLK_DMC_DIV_MPLL_PRE 12
-
-/*
- * Total number of clocks of CMU_DMC.
- * NOTE: Must be equal to highest clock ID increased by one.
- */
-#define NR_CLKS_DMC 13
-
-#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H */
--
2.9.3
^ permalink raw reply related
* [PATCH 3/4] pinctrl: samsung: Remove support for Exynos4415 (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>
Support for Exynos4415 is going away because there are no internal nor
external users.
Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the drivers.
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
drivers/pinctrl/samsung/pinctrl-exynos.c | 75 -------------------------------
drivers/pinctrl/samsung/pinctrl-samsung.c | 2 -
drivers/pinctrl/samsung/pinctrl-samsung.h | 1 -
3 files changed, 78 deletions(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 07409fde02b2..24814db251a7 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -919,81 +919,6 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
},
};
-/* pin banks of exynos4415 pin-controller 0 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks0[] = {
- EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
- EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
- EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
- EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
- EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
- EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
- EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
- EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
- EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
- EXYNOS_PIN_BANK_EINTG(1, 0x1C0, "gpf2", 0x38),
-};
-
-/* pin banks of exynos4415 pin-controller 1 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks1[] = {
- EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
- EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
- EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
- EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
- EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpl0", 0x18),
- EXYNOS_PIN_BANK_EINTN(6, 0x120, "mp00"),
- EXYNOS_PIN_BANK_EINTN(4, 0x140, "mp01"),
- EXYNOS_PIN_BANK_EINTN(6, 0x160, "mp02"),
- EXYNOS_PIN_BANK_EINTN(8, 0x180, "mp03"),
- EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "mp04"),
- EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "mp05"),
- EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "mp06"),
- EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
- EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
- EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
- EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
- EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
- EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
- EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
- EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
- EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos4415 pin-controller 2 */
-static const struct samsung_pin_bank_data exynos4415_pin_banks2[] = {
- EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
- EXYNOS_PIN_BANK_EINTN(2, 0x000, "etc1"),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4415 SoC. Exynos4415 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-const struct samsung_pin_ctrl exynos4415_pin_ctrl[] = {
- {
- /* pin-controller instance 0 data */
- .pin_banks = exynos4415_pin_banks0,
- .nr_banks = ARRAY_SIZE(exynos4415_pin_banks0),
- .eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
- }, {
- /* pin-controller instance 1 data */
- .pin_banks = exynos4415_pin_banks1,
- .nr_banks = ARRAY_SIZE(exynos4415_pin_banks1),
- .eint_gpio_init = exynos_eint_gpio_init,
- .eint_wkup_init = exynos_eint_wkup_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
- }, {
- /* pin-controller instance 2 data */
- .pin_banks = exynos4415_pin_banks2,
- .nr_banks = ARRAY_SIZE(exynos4415_pin_banks2),
- .eint_gpio_init = exynos_eint_gpio_init,
- .suspend = exynos_pinctrl_suspend,
- .resume = exynos_pinctrl_resume,
- },
-};
-
/* pin banks of exynos5250 pin-controller 0 */
static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = {
EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 41e62391c33c..3bc925f61b71 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1238,8 +1238,6 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = (void *)exynos4210_pin_ctrl },
{ .compatible = "samsung,exynos4x12-pinctrl",
.data = (void *)exynos4x12_pin_ctrl },
- { .compatible = "samsung,exynos4415-pinctrl",
- .data = (void *)exynos4415_pin_ctrl },
{ .compatible = "samsung,exynos5250-pinctrl",
.data = (void *)exynos5250_pin_ctrl },
{ .compatible = "samsung,exynos5260-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 043cb6c11180..6f7ce7539a00 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -273,7 +273,6 @@ struct samsung_pmx_func {
extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[];
extern const struct samsung_pin_ctrl exynos5410_pin_ctrl[];
--
2.9.3
^ permalink raw reply related
* [PATCH 4/4] drm: exynos: Remove support for Exynos4415 (SoC not supported anymore)
From: Krzysztof Kozlowski @ 2017-01-14 12:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>
Support for Exynos4415 is going away because there are no internal nor
external users.
Since commit 46dcf0ff0de3 ("ARM: dts: exynos: Remove exynos4415.dtsi"),
the platform cannot be instantiated so remove also the drivers.
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
.../devicetree/bindings/display/exynos/exynos_dsim.txt | 1 -
.../bindings/display/exynos/samsung-fimd.txt | 1 -
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 15 +--------------
drivers/gpu/drm/exynos/exynos_drm_fimd.c | 18 ++----------------
4 files changed, 3 insertions(+), 32 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
index a78265993665..ca5204b3bc21 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
@@ -4,7 +4,6 @@ Required properties:
- compatible: value should be one of the following
"samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
- "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
diff --git a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
index c7c6b9af87ac..c7ffe614ab2d 100644
--- a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
+++ b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
@@ -11,7 +11,6 @@ Required properties:
"samsung,s5pv210-fimd"; /* for S5PV210 SoC */
"samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
"samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
- "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
"samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */
"samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 812e2ec0761d..ef6f9c6de098 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -86,7 +86,7 @@
#define DSIM_SYNC_INFORM (1 << 27)
#define DSIM_EOT_DISABLE (1 << 28)
#define DSIM_MFLUSH_VS (1 << 29)
-/* This flag is valid only for exynos3250/3472/4415/5260/5430 */
+/* This flag is valid only for exynos3250/3472/5260/5430 */
#define DSIM_CLKLANE_STOP (1 << 30)
/* DSIM_ESCMODE */
@@ -473,17 +473,6 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
.reg_values = reg_values,
};
-static const struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
- .reg_ofs = exynos_reg_ofs,
- .plltmr_reg = 0x58,
- .has_clklane_stop = 1,
- .num_clks = 2,
- .max_freq = 1000,
- .wait_for_reset = 1,
- .num_bits_resol = 11,
- .reg_values = reg_values,
-};
-
static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x58,
@@ -521,8 +510,6 @@ static const struct of_device_id exynos_dsi_of_match[] = {
.data = &exynos3_dsi_driver_data },
{ .compatible = "samsung,exynos4210-mipi-dsi",
.data = &exynos4_dsi_driver_data },
- { .compatible = "samsung,exynos4415-mipi-dsi",
- .data = &exynos4415_dsi_driver_data },
{ .compatible = "samsung,exynos5410-mipi-dsi",
.data = &exynos5_dsi_driver_data },
{ .compatible = "samsung,exynos5422-mipi-dsi",
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 745cfbdf6b39..7ba50549283e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -71,10 +71,10 @@
#define TRIGCON 0x1A4
#define TRGMODE_ENABLE (1 << 0)
#define SWTRGCMD_ENABLE (1 << 1)
-/* Exynos3250, 3472, 4415, 5260 5410, 5420 and 5422 only supported. */
+/* Exynos3250, 3472, 5260 5410, 5420 and 5422 only supported. */
#define HWTRGEN_ENABLE (1 << 3)
#define HWTRGMASK_ENABLE (1 << 4)
-/* Exynos3250, 3472, 4415, 5260, 5420 and 5422 only supported. */
+/* Exynos3250, 3472, 5260, 5420 and 5422 only supported. */
#define HWTRIGEN_PER_ENABLE (1 << 31)
/* display mode change control register except exynos4 */
@@ -140,18 +140,6 @@ static struct fimd_driver_data exynos4_fimd_driver_data = {
.has_vtsel = 1,
};
-static struct fimd_driver_data exynos4415_fimd_driver_data = {
- .timing_base = 0x20000,
- .lcdblk_offset = 0x210,
- .lcdblk_vt_shift = 10,
- .lcdblk_bypass_shift = 1,
- .trg_type = I80_HW_TRG,
- .has_shadowcon = 1,
- .has_vidoutcon = 1,
- .has_vtsel = 1,
- .has_trigger_per_te = 1,
-};
-
static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x20000,
.lcdblk_offset = 0x214,
@@ -212,8 +200,6 @@ static const struct of_device_id fimd_driver_dt_match[] = {
.data = &exynos3_fimd_driver_data },
{ .compatible = "samsung,exynos4210-fimd",
.data = &exynos4_fimd_driver_data },
- { .compatible = "samsung,exynos4415-fimd",
- .data = &exynos4415_fimd_driver_data },
{ .compatible = "samsung,exynos5250-fimd",
.data = &exynos5_fimd_driver_data },
{ .compatible = "samsung,exynos5420-fimd",
--
2.9.3
^ permalink raw reply related
* [PATCH 3/4] iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs
From: Jonathan Cameron @ 2017-01-14 13:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFBinCAuTGrgOC5wNqoGfCb6NeQUsBCB9TreLPrjLQNT+h-XzA@mail.gmail.com>
On 13/01/17 23:48, Martin Blumenstingl wrote:
> Hi Heiner,
>
> On Fri, Jan 13, 2017 at 9:26 PM, Heiner Kallweit <hkallweit1@gmail.com> wrote:
> [snip]
>>>>> +static int meson_saradc_read_raw_sample(struct iio_dev *indio_dev,
>>>>> + const struct iio_chan_spec *chan,
>>>>> + int *val)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> + int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
>>>>> +
>>>>> + ret = meson_saradc_wait_busy_clear(indio_dev);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + regmap_read(priv->regmap, SAR_ADC_REG0, ®val);
>>>> The resulting regval value isn't used, therefore this statement doesn't seem
>>>> to be needed.
>>> I can probably replace this with "0", good catch!
>>>
>>>> In the vendor driver there is such a dummy statement before reading the busy
>>>> flags in REG0 after starting sampling. Reason seems to be a potential race
>>>> when we try to read the busy flags before the sampling engine has set them.
>>>> This isn't needed in meson_saradc_wait_busy_clear here as an udelay(1) is
>>>> done first always.
>>> do you think it's worth adding a comment here that a do ... while loop
>>> is there on purpose?
>>>
>> Yes, a hint would be good that there's a potential race.
>> Else there's a good chance that a future refactoring introduces a regression.
> indeed, a comment will be part of v2
>
>>>>> +
>>>>> + while (meson_saradc_get_fifo_count(indio_dev) > 0 &&
>>>> IMHO this loop isn't needed. When we come here the FIFO contains exactly
>>>> one element. This is true also in averaging mode as the averaging engine
>>>> writes only the resulting mean value to the FIFO.
>>>>
>>>> And we can't have multiple samples active in parallel due to the locking
>>>> done in meson_saradc_get_sample.
>>>>
>>>> By the way: I use an IRQ here to wake up when the FIFO contains one
>>>> element. But as you wrote: It's not clear whether this works on all
>>>> Meson systems.
>>> maybe I should switch to IRQ mode as even the old Meson6 vendor kernel
>>> sources indicate that the SAR ADC has IRQ support?
>>>
>> As you like. We can also add interrupt mode later (but leave polling intact)
>> and activate it only if an interrupt is set in DT.
>> This way we'd have a fallback in case there should be a problem with
>> interrupt mode on some system.
> I'm fine with either way, my idea was to keep it simple for the start.
> as a side-note: even if we get rid of polling mode we still need
> something like meson_saradc_wait_busy_clear(), because it's required
> to stop sampling (at least in some cases) according to the datasheet:
> "To stop sampling, simply set This bit and wait for all processing
> modules to no longer indicate that they are busy."
>
>>>>> + count < SAR_ADC_MAX_FIFO_SIZE) {
>>>>> + regmap_read(priv->regmap, SAR_ADC_FIFO_RD, ®val);
>>>>> +
>>>>> + fifo_chan = FIELD_GET(SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
>>>>> + if (fifo_chan == chan->channel) {
>>>>> + fifo_val = FIELD_GET(SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
>>>>> + regval) & SAR_ADC_VALUE_MASK(priv);
>>>>> + sum += fifo_val;
>>>>> + count++;
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + if (!count)
>>>>> + return -ENOENT;
>>>>> +
>>>>> + *val = sum / count;
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_set_averaging(struct iio_dev *indio_dev,
>>>>> + const struct iio_chan_spec *chan,
>>>>> + enum meson_saradc_avg_mode mode,
>>>>> + enum meson_saradc_num_samples samples)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> + u32 val;
>>>>> +
>>>>> + val = samples << SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(chan->channel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_AVG_CNTL,
>>>>> + SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(chan->channel),
>>>>> + val);
>>>>> +
>>>>> + val = mode << SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(chan->channel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_AVG_CNTL,
>>>>> + SAR_ADC_AVG_CNTL_AVG_MODE_MASK(chan->channel), val);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_enable_channel(struct iio_dev *indio_dev,
>>>>> + const struct iio_chan_spec *chan)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> + u32 regval;
>>>>> +
>>>>> + /* the SAR ADC engine allows sampling multiple channels at the same
>>>>> + * time. to keep it simple we're only working with one *internal*
>>>>> + * channel, which starts counting at index 0 (which means: count = 1).
>>>>> + */
>>>>> + regval = FIELD_PREP(SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_CHAN_LIST,
>>>>> + SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
>>>>> +
>>>>> + /* map channel index 0 to the channel which we want to read */
>>>>> + regval = FIELD_PREP(SAR_ADC_CHAN_CHAN_ENTRY_MASK(0), chan->channel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_CHAN_LIST,
>>>>> + SAR_ADC_CHAN_CHAN_ENTRY_MASK(0), regval);
>>>>> +
>>>>> + regval = FIELD_PREP(SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_MUX_MASK,
>>>>> + chan->channel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DETECT_IDLE_SW,
>>>>> + SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_MUX_MASK,
>>>>> + regval);
>>>>> +
>>>>> + regval = FIELD_PREP(SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_MUX_SEL_MASK,
>>>>> + chan->channel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DETECT_IDLE_SW,
>>>>> + SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_MUX_SEL_MASK,
>>>>> + regval);
>>>>> +
>>>>> + if (chan->channel == 6)
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELTA_10,
>>>>> + SAR_ADC_DELTA_10_TEMP_SEL, 0);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_set_channel7_mux(struct iio_dev *indio_dev,
>>>>> + enum meson_saradc_chan7_mux_sel sel)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> + u32 regval;
>>>>> +
>>>>> + regval = FIELD_PREP(SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG3,
>>>>> + SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
>>>>> +
>>>>> + usleep_range(10, 20);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_start_sample_engine(struct iio_dev *indio_dev)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> +
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
>>>>> +
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>> + SAR_ADC_REG0_SAMPLING_START,
>>>>> + SAR_ADC_REG0_SAMPLING_START);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_stop_sample_engine(struct iio_dev *indio_dev)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> +
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>> + SAR_ADC_REG0_SAMPLING_STOP,
>>>>> + SAR_ADC_REG0_SAMPLING_STOP);
>>>>> +
>>>>> + /* wait until all modules are stopped */
>>>>> + meson_saradc_wait_busy_clear(indio_dev);
>>>>> +
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_lock(struct iio_dev *indio_dev)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> + int val;
>>>>> +
>>>>> + mutex_lock(&indio_dev->mlock);
>>>>> +
>>>>> + /* prevent BL30 from using the SAR ADC while we are using it */
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELAY,
>>>>> + SAR_ADC_DELAY_KERNEL_BUSY,
>>>>> + SAR_ADC_DELAY_KERNEL_BUSY);
>>>>> +
>>>>> + /* wait until BL30 releases it's lock (so we can use the SAR ADC) */
>>>>> + do {
>>>>> + udelay(1);
>>>>> + regmap_read(priv->regmap, SAR_ADC_DELAY, &val);
>>>>> + } while (val & SAR_ADC_DELAY_BL30_BUSY);
>>>>> +}
>>>>> +
>>>>> +static void meson_saradc_unlock(struct iio_dev *indio_dev)
>>>>> +{
>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>> +
>>>>> + /* allow BL30 to use the SAR ADC again */
>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELAY,
>>>>> + SAR_ADC_DELAY_KERNEL_BUSY, 0);
>>>>> +
>>>>> + mutex_unlock(&indio_dev->mlock);
>>>>> +}
>>>>> +
>>>>> +static int meson_saradc_get_sample(struct iio_dev *indio_dev,
>>>>> + const struct iio_chan_spec *chan,
>>>>> + enum meson_saradc_avg_mode avg_mode,
>>>>> + enum meson_saradc_num_samples avg_samples,
>>>>> + int *val)
>>>>> +{
>>>>> + int ret, tmp;
>>>>> +
>>>>> + meson_saradc_lock(indio_dev);
>>>>> +
>>>>> + /* clear old values from the FIFO buffer, ignoring errors */
>>>>> + meson_saradc_read_raw_sample(indio_dev, chan, &tmp);
>>>>> +
>>>>> + meson_saradc_set_averaging(indio_dev, chan, avg_mode, avg_samples);
>>>>> +
>>>>> + meson_saradc_enable_channel(indio_dev, chan);
>>>>> +
>>>>> + meson_saradc_start_sample_engine(indio_dev);
>>>>> + ret = meson_saradc_read_raw_sample(indio_dev, chan, val);
>>>>> + meson_saradc_stop_sample_engine(indio_dev);
>>>>> +
>>>>> + meson_saradc_unlock(indio_dev);
>>>>> +
>>>>> + if (ret) {
>>>>> + dev_warn(&indio_dev->dev,
>>>> Using the struct device in indio_dev results in IMHO ugly messages like
>>>> iio iio:device0: already initialized by BL30
>>>>
>>>> We should use the parent instead, this is more readable:
>>>> meson-saradc c1108680.adc: already initialized by BL30
>>>>
>>>> For this we need to move the assignment to indio_dev->dev.parent
>>>> in probe, else messages may be written when parent isn't set yet.
>>> indeed, I'll change this - thanks for the hint!
> a little correction on this: I am all for setting the parent early.
> However, I think that devm_iio_device_alloc() itself should take care
> of building the device name correctly (to prevent code-duplication
> across drivers in drivers/iio/*).
> as an example: phy_create() does this (which includes the OF node
> name): dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
> iio_device_alloc does it like this (which is obviously missing the OF
> node name): dev_set_name(&dev->dev, "iio:device%d", dev->id);
>
Propose a patch if you would like to.
People 'shouldn't' be relying on this naming so hopefully we'll get
away with such an user space interface change without anyone noticing!
Jonathan
>
> Regards,
> Martin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH 3/4] iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs
From: Jonathan Cameron @ 2017-01-14 14:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3e32fc4b-d28c-c003-d292-39cad5179839@kernel.org>
On 14/01/17 13:57, Jonathan Cameron wrote:
> On 13/01/17 23:48, Martin Blumenstingl wrote:
>> Hi Heiner,
>>
>> On Fri, Jan 13, 2017 at 9:26 PM, Heiner Kallweit <hkallweit1@gmail.com> wrote:
>> [snip]
>>>>>> +static int meson_saradc_read_raw_sample(struct iio_dev *indio_dev,
>>>>>> + const struct iio_chan_spec *chan,
>>>>>> + int *val)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> + int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
>>>>>> +
>>>>>> + ret = meson_saradc_wait_busy_clear(indio_dev);
>>>>>> + if (ret)
>>>>>> + return ret;
>>>>>> +
>>>>>> + regmap_read(priv->regmap, SAR_ADC_REG0, ®val);
>>>>> The resulting regval value isn't used, therefore this statement doesn't seem
>>>>> to be needed.
>>>> I can probably replace this with "0", good catch!
>>>>
>>>>> In the vendor driver there is such a dummy statement before reading the busy
>>>>> flags in REG0 after starting sampling. Reason seems to be a potential race
>>>>> when we try to read the busy flags before the sampling engine has set them.
>>>>> This isn't needed in meson_saradc_wait_busy_clear here as an udelay(1) is
>>>>> done first always.
>>>> do you think it's worth adding a comment here that a do ... while loop
>>>> is there on purpose?
>>>>
>>> Yes, a hint would be good that there's a potential race.
>>> Else there's a good chance that a future refactoring introduces a regression.
>> indeed, a comment will be part of v2
>>
>>>>>> +
>>>>>> + while (meson_saradc_get_fifo_count(indio_dev) > 0 &&
>>>>> IMHO this loop isn't needed. When we come here the FIFO contains exactly
>>>>> one element. This is true also in averaging mode as the averaging engine
>>>>> writes only the resulting mean value to the FIFO.
>>>>>
>>>>> And we can't have multiple samples active in parallel due to the locking
>>>>> done in meson_saradc_get_sample.
>>>>>
>>>>> By the way: I use an IRQ here to wake up when the FIFO contains one
>>>>> element. But as you wrote: It's not clear whether this works on all
>>>>> Meson systems.
>>>> maybe I should switch to IRQ mode as even the old Meson6 vendor kernel
>>>> sources indicate that the SAR ADC has IRQ support?
>>>>
>>> As you like. We can also add interrupt mode later (but leave polling intact)
>>> and activate it only if an interrupt is set in DT.
>>> This way we'd have a fallback in case there should be a problem with
>>> interrupt mode on some system.
>> I'm fine with either way, my idea was to keep it simple for the start.
>> as a side-note: even if we get rid of polling mode we still need
>> something like meson_saradc_wait_busy_clear(), because it's required
>> to stop sampling (at least in some cases) according to the datasheet:
>> "To stop sampling, simply set This bit and wait for all processing
>> modules to no longer indicate that they are busy."
>>
>>>>>> + count < SAR_ADC_MAX_FIFO_SIZE) {
>>>>>> + regmap_read(priv->regmap, SAR_ADC_FIFO_RD, ®val);
>>>>>> +
>>>>>> + fifo_chan = FIELD_GET(SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
>>>>>> + if (fifo_chan == chan->channel) {
>>>>>> + fifo_val = FIELD_GET(SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
>>>>>> + regval) & SAR_ADC_VALUE_MASK(priv);
>>>>>> + sum += fifo_val;
>>>>>> + count++;
>>>>>> + }
>>>>>> + }
>>>>>> +
>>>>>> + if (!count)
>>>>>> + return -ENOENT;
>>>>>> +
>>>>>> + *val = sum / count;
>>>>>> +
>>>>>> + return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_set_averaging(struct iio_dev *indio_dev,
>>>>>> + const struct iio_chan_spec *chan,
>>>>>> + enum meson_saradc_avg_mode mode,
>>>>>> + enum meson_saradc_num_samples samples)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> + u32 val;
>>>>>> +
>>>>>> + val = samples << SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(chan->channel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_AVG_CNTL,
>>>>>> + SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(chan->channel),
>>>>>> + val);
>>>>>> +
>>>>>> + val = mode << SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(chan->channel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_AVG_CNTL,
>>>>>> + SAR_ADC_AVG_CNTL_AVG_MODE_MASK(chan->channel), val);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_enable_channel(struct iio_dev *indio_dev,
>>>>>> + const struct iio_chan_spec *chan)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> + u32 regval;
>>>>>> +
>>>>>> + /* the SAR ADC engine allows sampling multiple channels at the same
>>>>>> + * time. to keep it simple we're only working with one *internal*
>>>>>> + * channel, which starts counting at index 0 (which means: count = 1).
>>>>>> + */
>>>>>> + regval = FIELD_PREP(SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_CHAN_LIST,
>>>>>> + SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
>>>>>> +
>>>>>> + /* map channel index 0 to the channel which we want to read */
>>>>>> + regval = FIELD_PREP(SAR_ADC_CHAN_CHAN_ENTRY_MASK(0), chan->channel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_CHAN_LIST,
>>>>>> + SAR_ADC_CHAN_CHAN_ENTRY_MASK(0), regval);
>>>>>> +
>>>>>> + regval = FIELD_PREP(SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_MUX_MASK,
>>>>>> + chan->channel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DETECT_IDLE_SW,
>>>>>> + SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_MUX_MASK,
>>>>>> + regval);
>>>>>> +
>>>>>> + regval = FIELD_PREP(SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_MUX_SEL_MASK,
>>>>>> + chan->channel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DETECT_IDLE_SW,
>>>>>> + SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_MUX_SEL_MASK,
>>>>>> + regval);
>>>>>> +
>>>>>> + if (chan->channel == 6)
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELTA_10,
>>>>>> + SAR_ADC_DELTA_10_TEMP_SEL, 0);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_set_channel7_mux(struct iio_dev *indio_dev,
>>>>>> + enum meson_saradc_chan7_mux_sel sel)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> + u32 regval;
>>>>>> +
>>>>>> + regval = FIELD_PREP(SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG3,
>>>>>> + SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
>>>>>> +
>>>>>> + usleep_range(10, 20);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_start_sample_engine(struct iio_dev *indio_dev)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> +
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
>>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
>>>>>> +
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>>> + SAR_ADC_REG0_SAMPLING_START,
>>>>>> + SAR_ADC_REG0_SAMPLING_START);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_stop_sample_engine(struct iio_dev *indio_dev)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> +
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>>> + SAR_ADC_REG0_SAMPLING_STOP,
>>>>>> + SAR_ADC_REG0_SAMPLING_STOP);
>>>>>> +
>>>>>> + /* wait until all modules are stopped */
>>>>>> + meson_saradc_wait_busy_clear(indio_dev);
>>>>>> +
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_REG0,
>>>>>> + SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_lock(struct iio_dev *indio_dev)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> + int val;
>>>>>> +
>>>>>> + mutex_lock(&indio_dev->mlock);
>>>>>> +
>>>>>> + /* prevent BL30 from using the SAR ADC while we are using it */
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELAY,
>>>>>> + SAR_ADC_DELAY_KERNEL_BUSY,
>>>>>> + SAR_ADC_DELAY_KERNEL_BUSY);
>>>>>> +
>>>>>> + /* wait until BL30 releases it's lock (so we can use the SAR ADC) */
>>>>>> + do {
>>>>>> + udelay(1);
>>>>>> + regmap_read(priv->regmap, SAR_ADC_DELAY, &val);
>>>>>> + } while (val & SAR_ADC_DELAY_BL30_BUSY);
>>>>>> +}
>>>>>> +
>>>>>> +static void meson_saradc_unlock(struct iio_dev *indio_dev)
>>>>>> +{
>>>>>> + struct meson_saradc_priv *priv = iio_priv(indio_dev);
>>>>>> +
>>>>>> + /* allow BL30 to use the SAR ADC again */
>>>>>> + regmap_update_bits(priv->regmap, SAR_ADC_DELAY,
>>>>>> + SAR_ADC_DELAY_KERNEL_BUSY, 0);
>>>>>> +
>>>>>> + mutex_unlock(&indio_dev->mlock);
>>>>>> +}
>>>>>> +
>>>>>> +static int meson_saradc_get_sample(struct iio_dev *indio_dev,
>>>>>> + const struct iio_chan_spec *chan,
>>>>>> + enum meson_saradc_avg_mode avg_mode,
>>>>>> + enum meson_saradc_num_samples avg_samples,
>>>>>> + int *val)
>>>>>> +{
>>>>>> + int ret, tmp;
>>>>>> +
>>>>>> + meson_saradc_lock(indio_dev);
>>>>>> +
>>>>>> + /* clear old values from the FIFO buffer, ignoring errors */
>>>>>> + meson_saradc_read_raw_sample(indio_dev, chan, &tmp);
>>>>>> +
>>>>>> + meson_saradc_set_averaging(indio_dev, chan, avg_mode, avg_samples);
>>>>>> +
>>>>>> + meson_saradc_enable_channel(indio_dev, chan);
>>>>>> +
>>>>>> + meson_saradc_start_sample_engine(indio_dev);
>>>>>> + ret = meson_saradc_read_raw_sample(indio_dev, chan, val);
>>>>>> + meson_saradc_stop_sample_engine(indio_dev);
>>>>>> +
>>>>>> + meson_saradc_unlock(indio_dev);
>>>>>> +
>>>>>> + if (ret) {
>>>>>> + dev_warn(&indio_dev->dev,
>>>>> Using the struct device in indio_dev results in IMHO ugly messages like
>>>>> iio iio:device0: already initialized by BL30
>>>>>
>>>>> We should use the parent instead, this is more readable:
>>>>> meson-saradc c1108680.adc: already initialized by BL30
>>>>>
>>>>> For this we need to move the assignment to indio_dev->dev.parent
>>>>> in probe, else messages may be written when parent isn't set yet.
>>>> indeed, I'll change this - thanks for the hint!
>> a little correction on this: I am all for setting the parent early.
>> However, I think that devm_iio_device_alloc() itself should take care
>> of building the device name correctly (to prevent code-duplication
>> across drivers in drivers/iio/*).
>> as an example: phy_create() does this (which includes the OF node
>> name): dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
>> iio_device_alloc does it like this (which is obviously missing the OF
>> node name): dev_set_name(&dev->dev, "iio:device%d", dev->id);
>>
> Propose a patch if you would like to.
> People 'shouldn't' be relying on this naming so hopefully we'll get
> away with such an user space interface change without anyone noticing!
>
Err, hang on. I didn't think this through. This same name is used
for the naming of the chardev. Changing it is a nonstarter I'm
afraid unless there is some way of splitting the two uses.
Jonathan
> Jonathan
>>
>> Regards,
>> Martin
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox