* [PATCH v17 3/4] arm64: dts: mt8173: Add GCE node
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao@mediatek.com>
This patch adds the device node of the GCE hardware for CMDQ module.
Signed-off-by: HS Liao <hs.liao@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 1c71e25..d50c044 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -414,6 +414,16 @@
status = "disabled";
};
+ gce: gce at 10212000 {
+ compatible = "mediatek,mt8173-gce";
+ reg = <0 0x10212000 0 0x1000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+
+ #mbox-cells = <2>;
+ };
+
mipi_tx0: mipi-dphy at 10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
--
1.9.1
^ permalink raw reply related
* [PATCH v17 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao@mediatek.com>
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.
Signed-off-by: HS Liao <hs.liao@mediatek.com>
Signed-off-by: CK Hu <ck.hu@mediatek.com>
---
drivers/mailbox/Kconfig | 10 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mtk-cmdq-mailbox.c | 632 +++++++++++++++++++++++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 75 ++++
4 files changed, 719 insertions(+)
create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 11eebfe..5a4af2d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -143,4 +143,14 @@ config BCM_PDC_MBOX
Mailbox implementation for the Broadcom PDC ring manager,
which provides access to various offload engines on Broadcom
SoCs. Say Y here if you want to use the Broadcom PDC.
+
+config MTK_CMDQ_MBOX
+ bool "MediaTek CMDQ Mailbox Support"
+ depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
+ select MTK_INFRACFG
+ help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index ace6fed..b904bed 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -29,3 +29,5 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
obj-$(CONFIG_HI6220_MBOX) += hi6220-mailbox.o
obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 0000000..8771e57
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+
+#define CMDQ_THR_MAX_COUNT 3 /* main, sub, general(misc) */
+#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_TIMEOUT_MS 1000
+#define CMDQ_IRQ_MASK 0xffff
+#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS 0x10
+#define CMDQ_THR_SLOT_CYCLES 0x30
+
+#define CMDQ_THR_BASE 0x100
+#define CMDQ_THR_SIZE 0x80
+#define CMDQ_THR_WARM_RESET 0x00
+#define CMDQ_THR_ENABLE_TASK 0x04
+#define CMDQ_THR_SUSPEND_TASK 0x08
+#define CMDQ_THR_CURR_STATUS 0x0c
+#define CMDQ_THR_IRQ_STATUS 0x10
+#define CMDQ_THR_IRQ_ENABLE 0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR 0x24
+#define CMDQ_THR_WAIT_TOKEN 0x30
+
+#define CMDQ_THR_ENABLED 0x1
+#define CMDQ_THR_DISABLED 0x0
+#define CMDQ_THR_SUSPEND 0x1
+#define CMDQ_THR_RESUME 0x0
+#define CMDQ_THR_STATUS_SUSPENDED BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES 0x3200
+#define CMDQ_THR_IRQ_DONE 0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITING BIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET 0x10000000
+#define CMDQ_JUMP_BY_PA 0x10000001
+
+struct cmdq_thread {
+ struct mbox_chan *chan;
+ void __iomem *base;
+ struct list_head task_busy_list;
+ struct timer_list timeout;
+ bool atomic_exec;
+};
+
+struct cmdq_task {
+ struct cmdq *cmdq;
+ struct list_head list_entry;
+ dma_addr_t pa_base;
+ struct cmdq_thread *thread;
+ struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq_clk_release {
+ struct cmdq *cmdq;
+ struct work_struct release_work;
+};
+
+struct cmdq {
+ struct mbox_controller mbox;
+ void __iomem *base;
+ u32 irq;
+ struct workqueue_struct *clk_release_wq;
+ struct cmdq_thread thread[CMDQ_THR_MAX_COUNT];
+ struct clk *clock;
+ bool suspended;
+};
+
+static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ u32 status;
+
+ writel(CMDQ_THR_SUSPEND, thread->base + CMDQ_THR_SUSPEND_TASK);
+
+ /* If already disabled, treat as suspended successful. */
+ if (!(readl(thread->base + CMDQ_THR_ENABLE_TASK) & CMDQ_THR_ENABLED))
+ return 0;
+
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_CURR_STATUS,
+ status, status & CMDQ_THR_STATUS_SUSPENDED, 0, 10)) {
+ dev_err(cmdq->mbox.dev, "suspend GCE thread 0x%x failed\n",
+ (u32)(thread->base - cmdq->base));
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void cmdq_thread_resume(struct cmdq_thread *thread)
+{
+ writel(CMDQ_THR_RESUME, thread->base + CMDQ_THR_SUSPEND_TASK);
+}
+
+static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ u32 warm_reset;
+
+ writel(CMDQ_THR_DO_WARM_RESET, thread->base + CMDQ_THR_WARM_RESET);
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_WARM_RESET,
+ warm_reset, !(warm_reset & CMDQ_THR_DO_WARM_RESET),
+ 0, 10)) {
+ dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x failed\n",
+ (u32)(thread->base - cmdq->base));
+ return -EFAULT;
+ }
+ writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
+ return 0;
+}
+
+static void cmdq_thread_disable(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+ cmdq_thread_reset(cmdq, thread);
+ writel(CMDQ_THR_DISABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+}
+
+/* notify GCE to re-fetch commands by setting GCE thread PC */
+static void cmdq_thread_invalidate_fetched_data(struct cmdq_thread *thread)
+{
+ writel(readl(thread->base + CMDQ_THR_CURR_ADDR),
+ thread->base + CMDQ_THR_CURR_ADDR);
+}
+
+static void cmdq_task_insert_into_thread(struct cmdq_task *task)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ struct cmdq_thread *thread = task->thread;
+ struct cmdq_task *prev_task = list_last_entry(
+ &thread->task_busy_list, typeof(*task), list_entry);
+ u64 *prev_task_base = prev_task->pkt->va_base;
+
+ /* let previous task jump to this task */
+ dma_sync_single_for_cpu(dev, prev_task->pa_base,
+ prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+ prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
+ (u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base;
+ dma_sync_single_for_device(dev, prev_task->pa_base,
+ prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
+
+ cmdq_thread_invalidate_fetched_data(thread);
+}
+
+static bool cmdq_command_is_wfe(u64 cmd)
+{
+ u64 wfe_option = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+ u64 wfe_op = (u64)(CMDQ_CODE_WFE << CMDQ_OP_CODE_SHIFT) << 32;
+ u64 wfe_mask = (u64)CMDQ_OP_CODE_MASK << 32 | 0xffffffff;
+
+ return ((cmd & wfe_mask) == (wfe_op | wfe_option));
+}
+
+/* we assume tasks in the same display GCE thread are waiting the same event. */
+static void cmdq_task_remove_wfe(struct cmdq_task *task)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ u64 *base = task->pkt->va_base;
+ int i;
+
+ dma_sync_single_for_cpu(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+ for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
+ if (cmdq_command_is_wfe(base[i]))
+ base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
+ CMDQ_JUMP_PASS;
+ dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+}
+
+static bool cmdq_thread_is_in_wfe(struct cmdq_thread *thread)
+{
+ return readl(thread->base + CMDQ_THR_WAIT_TOKEN) & CMDQ_THR_IS_WAITING;
+}
+
+static void cmdq_thread_wait_end(struct cmdq_thread *thread,
+ unsigned long end_pa)
+{
+ struct device *dev = thread->chan->mbox->dev;
+ unsigned long curr_pa;
+
+ if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_CURR_ADDR,
+ curr_pa, curr_pa == end_pa, 1, 20))
+ dev_err(dev, "GCE thread cannot run to end.\n");
+}
+
+static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread *thread)
+{
+ struct cmdq *cmdq;
+ struct cmdq_task *task;
+ unsigned long curr_pa, end_pa, flags;
+
+ cmdq = dev_get_drvdata(thread->chan->mbox->dev);
+
+ /* Client should not flush new tasks if suspended. */
+ WARN_ON(cmdq->suspended);
+
+ task = kzalloc(sizeof(*task), GFP_ATOMIC);
+ task->cmdq = cmdq;
+ INIT_LIST_HEAD(&task->list_entry);
+ task->pa_base = dma_map_single(cmdq->mbox.dev, pkt->va_base,
+ pkt->cmd_buf_size, DMA_TO_DEVICE);
+ task->thread = thread;
+ task->pkt = pkt;
+
+ if (list_empty(&thread->task_busy_list)) {
+ /*
+ * Unlock for clk prepare (sleeping function).
+ * This is safe since clk_prepare_enable has internal locks.
+ */
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ WARN_ON(clk_prepare_enable(cmdq->clock) < 0);
+ spin_lock_irqsave(&thread->chan->lock, flags);
+
+ WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
+
+ writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+ writel(task->pa_base + pkt->cmd_buf_size,
+ thread->base + CMDQ_THR_END_ADDR);
+ writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
+ writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
+
+ mod_timer(&thread->timeout,
+ jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
+ } else {
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+ end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
+
+ /*
+ * Atomic execution should remove the following wfe, i.e. only
+ * wait event at first task, and prevent to pause when running.
+ */
+ if (thread->atomic_exec) {
+ /* GCE is executing if command is not WFE */
+ if (!cmdq_thread_is_in_wfe(thread)) {
+ cmdq_thread_resume(thread);
+ cmdq_thread_wait_end(thread, end_pa);
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+ /* set to this task directly */
+ writel(task->pa_base,
+ thread->base + CMDQ_THR_CURR_ADDR);
+ } else {
+ cmdq_task_insert_into_thread(task);
+ cmdq_task_remove_wfe(task);
+ smp_mb(); /* modify jump before enable thread */
+ }
+ } else {
+ /* check boundary */
+ if (curr_pa == end_pa - CMDQ_INST_SIZE ||
+ curr_pa == end_pa) {
+ /* set to this task directly */
+ writel(task->pa_base,
+ thread->base + CMDQ_THR_CURR_ADDR);
+ } else {
+ cmdq_task_insert_into_thread(task);
+ smp_mb(); /* modify jump before enable thread */
+ }
+ }
+ writel(task->pa_base + pkt->cmd_buf_size,
+ thread->base + CMDQ_THR_END_ADDR);
+ cmdq_thread_resume(thread);
+ }
+ list_move_tail(&task->list_entry, &thread->task_busy_list);
+}
+
+static void cmdq_task_exec_done(struct cmdq_task *task, bool err)
+{
+ struct device *dev = task->cmdq->mbox.dev;
+ struct cmdq_cb_data cmdq_cb_data;
+
+ dma_unmap_single(dev, task->pa_base, task->pkt->cmd_buf_size,
+ DMA_TO_DEVICE);
+ if (task->pkt->cb.cb) {
+ cmdq_cb_data.err = err;
+ cmdq_cb_data.data = task->pkt->cb.data;
+ task->pkt->cb.cb(cmdq_cb_data);
+ }
+ list_del(&task->list_entry);
+}
+
+static void cmdq_task_handle_error(struct cmdq_task *task)
+{
+ struct cmdq_thread *thread = task->thread;
+ struct cmdq_task *next_task;
+
+ dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
+ WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+ next_task = list_first_entry_or_null(&thread->task_busy_list,
+ struct cmdq_task, list_entry);
+ if (next_task)
+ writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+ cmdq_thread_resume(thread);
+}
+
+static void cmdq_clk_release_work(struct work_struct *work_item)
+{
+ struct cmdq_clk_release *clk_release = container_of(work_item,
+ struct cmdq_clk_release, release_work);
+ struct cmdq *cmdq = clk_release->cmdq;
+
+ clk_disable_unprepare(cmdq->clock);
+ kfree(clk_release);
+}
+
+static void cmdq_clk_release_schedule(struct cmdq *cmdq)
+{
+ struct cmdq_clk_release *clk_release;
+
+ clk_release = kmalloc(sizeof(*clk_release), GFP_ATOMIC);
+ clk_release->cmdq = cmdq;
+ INIT_WORK(&clk_release->release_work, cmdq_clk_release_work);
+ queue_work(cmdq->clk_release_wq, &clk_release->release_work);
+}
+
+static void cmdq_thread_irq_handler(struct cmdq *cmdq,
+ struct cmdq_thread *thread)
+{
+ struct cmdq_task *task, *tmp, *curr_task = NULL;
+ u32 curr_pa, irq_flag, task_end_pa;
+ bool err;
+
+ irq_flag = readl(thread->base + CMDQ_THR_IRQ_STATUS);
+ writel(~irq_flag, thread->base + CMDQ_THR_IRQ_STATUS);
+
+ /*
+ * When ISR call this function, another CPU core could run
+ * "release task" right before we acquire the spin lock, and thus
+ * reset / disable this GCE thread, so we need to check the enable
+ * bit of this GCE thread.
+ */
+ if (!(readl(thread->base + CMDQ_THR_ENABLE_TASK) & CMDQ_THR_ENABLED))
+ return;
+
+ if (irq_flag & CMDQ_THR_IRQ_ERROR)
+ err = true;
+ else if (irq_flag & CMDQ_THR_IRQ_DONE)
+ err = false;
+ else
+ return;
+
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+
+ list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+ list_entry) {
+ task_end_pa = task->pa_base + task->pkt->cmd_buf_size;
+ if (curr_pa >= task->pa_base && curr_pa < task_end_pa)
+ curr_task = task;
+
+ if (!curr_task || curr_pa == task_end_pa - CMDQ_INST_SIZE) {
+ cmdq_task_exec_done(task, false);
+ kfree(task);
+ } else if (err) {
+ cmdq_task_exec_done(task, true);
+ cmdq_task_handle_error(curr_task);
+ kfree(task);
+ }
+
+ if (curr_task)
+ break;
+ }
+
+ if (list_empty(&thread->task_busy_list)) {
+ cmdq_thread_disable(cmdq, thread);
+ cmdq_clk_release_schedule(cmdq);
+ } else {
+ mod_timer(&thread->timeout,
+ jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
+ }
+}
+
+static irqreturn_t cmdq_irq_handler(int irq, void *dev)
+{
+ struct cmdq *cmdq = dev;
+ unsigned long irq_status, flags = 0L;
+ int bit;
+
+ irq_status = readl(cmdq->base + CMDQ_CURR_IRQ_STATUS) & CMDQ_IRQ_MASK;
+ if (!(irq_status ^ CMDQ_IRQ_MASK))
+ return IRQ_NONE;
+
+ for_each_clear_bit(bit, &irq_status, fls(CMDQ_IRQ_MASK)) {
+ struct cmdq_thread *thread = &cmdq->thread[bit];
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ cmdq_thread_irq_handler(cmdq, thread);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ }
+ return IRQ_HANDLED;
+}
+
+static void cmdq_thread_handle_timeout(unsigned long data)
+{
+ struct cmdq_thread *thread = (struct cmdq_thread *)data;
+ struct cmdq *cmdq = container_of(thread->chan->mbox, struct cmdq, mbox);
+ struct cmdq_task *task, *tmp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&thread->chan->lock, flags);
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+ /*
+ * Although IRQ is disabled, GCE continues to execute.
+ * It may have pending IRQ before GCE thread is suspended,
+ * so check this condition again.
+ */
+ cmdq_thread_irq_handler(cmdq, thread);
+
+ if (list_empty(&thread->task_busy_list)) {
+ cmdq_thread_resume(thread);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+ return;
+ }
+
+ dev_err(cmdq->mbox.dev, "timeout\n");
+ list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+ list_entry) {
+ cmdq_task_exec_done(task, true);
+ kfree(task);
+ }
+
+ cmdq_thread_resume(thread);
+ cmdq_thread_disable(cmdq, thread);
+ cmdq_clk_release_schedule(cmdq);
+ spin_unlock_irqrestore(&thread->chan->lock, flags);
+}
+
+static int cmdq_suspend(struct device *dev)
+{
+ struct cmdq *cmdq = dev_get_drvdata(dev);
+ struct cmdq_thread *thread;
+ int i;
+ bool task_running = false;
+
+ cmdq->suspended = true;
+
+ for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
+ thread = &cmdq->thread[i];
+ if (!list_empty(&thread->task_busy_list)) {
+ task_running = true;
+ break;
+ }
+ }
+
+ if (task_running)
+ dev_warn(dev, "exist running task(s) in suspend\n");
+
+ flush_workqueue(cmdq->clk_release_wq);
+ return 0;
+}
+
+static int cmdq_resume(struct device *dev)
+{
+ struct cmdq *cmdq = dev_get_drvdata(dev);
+
+ cmdq->suspended = false;
+ return 0;
+}
+
+static int cmdq_remove(struct platform_device *pdev)
+{
+ struct cmdq *cmdq = platform_get_drvdata(pdev);
+
+ destroy_workqueue(cmdq->clk_release_wq);
+ mbox_controller_unregister(&cmdq->mbox);
+ return 0;
+}
+
+static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+ cmdq_task_exec(data, chan->con_priv);
+ return 0;
+}
+
+static int cmdq_mbox_startup(struct mbox_chan *chan)
+{
+ return 0;
+}
+
+static void cmdq_mbox_shutdown(struct mbox_chan *chan)
+{
+}
+
+static bool cmdq_mbox_last_tx_done(struct mbox_chan *chan)
+{
+ return true;
+}
+
+static const struct mbox_chan_ops cmdq_mbox_chan_ops = {
+ .send_data = cmdq_mbox_send_data,
+ .startup = cmdq_mbox_startup,
+ .shutdown = cmdq_mbox_shutdown,
+ .last_tx_done = cmdq_mbox_last_tx_done,
+};
+
+static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *sp)
+{
+ int ind = sp->args[0];
+ struct cmdq_thread *thread;
+
+ if (ind >= mbox->num_chans)
+ return ERR_PTR(-EINVAL);
+
+ thread = mbox->chans[ind].con_priv;
+ thread->atomic_exec = (sp->args[1] != 0);
+ thread->chan = &mbox->chans[ind];
+
+ return &mbox->chans[ind];
+}
+
+static int cmdq_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct cmdq *cmdq;
+ int err, i;
+
+ cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
+ if (!cmdq)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ cmdq->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(cmdq->base)) {
+ dev_err(dev, "failed to ioremap gce\n");
+ return PTR_ERR(cmdq->base);
+ }
+
+ cmdq->irq = platform_get_irq(pdev, 0);
+ if (!cmdq->irq) {
+ dev_err(dev, "failed to get irq\n");
+ return -EINVAL;
+ }
+ err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
+ "mtk_cmdq", cmdq);
+ if (err < 0) {
+ dev_err(dev, "failed to register ISR (%d)\n", err);
+ return err;
+ }
+
+ dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
+ dev, cmdq->base, cmdq->irq);
+
+ cmdq->clock = devm_clk_get(dev, "gce");
+ if (IS_ERR(cmdq->clock)) {
+ dev_err(dev, "failed to get gce clk\n");
+ return PTR_ERR(cmdq->clock);
+ }
+
+ cmdq->mbox.dev = dev;
+ cmdq->mbox.chans = devm_kcalloc(dev, CMDQ_THR_MAX_COUNT,
+ sizeof(*cmdq->mbox.chans), GFP_KERNEL);
+ if (!cmdq->mbox.chans)
+ return -ENOMEM;
+
+ cmdq->mbox.num_chans = CMDQ_THR_MAX_COUNT;
+ cmdq->mbox.ops = &cmdq_mbox_chan_ops;
+ cmdq->mbox.of_xlate = cmdq_xlate;
+
+ /* make use of TXDONE_BY_ACK */
+ cmdq->mbox.txdone_irq = false;
+ cmdq->mbox.txdone_poll = false;
+
+ for (i = 0; i < ARRAY_SIZE(cmdq->thread); i++) {
+ cmdq->thread[i].base = cmdq->base + CMDQ_THR_BASE +
+ CMDQ_THR_SIZE * i;
+ INIT_LIST_HEAD(&cmdq->thread[i].task_busy_list);
+ init_timer(&cmdq->thread[i].timeout);
+ cmdq->thread[i].timeout.function = cmdq_thread_handle_timeout;
+ cmdq->thread[i].timeout.data = (unsigned long)&cmdq->thread[i];
+ cmdq->mbox.chans[i].con_priv = &cmdq->thread[i];
+ }
+
+ err = mbox_controller_register(&cmdq->mbox);
+ if (err < 0) {
+ dev_err(dev, "failed to register mailbox: %d\n", err);
+ return err;
+ }
+
+ cmdq->clk_release_wq = alloc_ordered_workqueue(
+ "%s", WQ_MEM_RECLAIM | WQ_HIGHPRI,
+ "cmdq_clk_release");
+
+ platform_set_drvdata(pdev, cmdq);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cmdq_pm_ops = {
+ .suspend = cmdq_suspend,
+ .resume = cmdq_resume,
+};
+
+static const struct of_device_id cmdq_of_ids[] = {
+ {.compatible = "mediatek,mt8173-gce",},
+ {}
+};
+
+static struct platform_driver cmdq_drv = {
+ .probe = cmdq_probe,
+ .remove = cmdq_remove,
+ .driver = {
+ .name = "mtk_cmdq",
+ .pm = &cmdq_pm_ops,
+ .of_match_table = cmdq_of_ids,
+ }
+};
+
+builtin_platform_driver(cmdq_drv);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
new file mode 100644
index 0000000..3433c64
--- /dev/null
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MTK_CMDQ_MAILBOX_H__
+#define __MTK_CMDQ_MAILBOX_H__
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_OP_CODE_SHIFT 24
+#define CMDQ_JUMP_PASS CMDQ_INST_SIZE
+
+#define CMDQ_WFE_UPDATE BIT(31)
+#define CMDQ_WFE_WAIT BIT(15)
+#define CMDQ_WFE_WAIT_VALUE 0x1
+
+/*
+ * CMDQ_CODE_MASK:
+ * set write mask
+ * format: op mask
+ * CMDQ_CODE_WRITE:
+ * write value into target register
+ * format: op subsys address value
+ * CMDQ_CODE_JUMP:
+ * jump by offset
+ * format: op offset
+ * CMDQ_CODE_WFE:
+ * wait for event and clear
+ * it is just clear if no wait
+ * format: [wait] op event update:1 to_wait:1 wait:1
+ * [clear] op event update:1 to_wait:0 wait:0
+ * CMDQ_CODE_EOC:
+ * end of command
+ * format: op irq_flag
+ */
+enum cmdq_code {
+ CMDQ_CODE_MASK = 0x02,
+ CMDQ_CODE_WRITE = 0x04,
+ CMDQ_CODE_JUMP = 0x10,
+ CMDQ_CODE_WFE = 0x20,
+ CMDQ_CODE_EOC = 0x40,
+};
+
+struct cmdq_cb_data {
+ bool err;
+ void *data;
+};
+
+typedef void (*cmdq_async_flush_cb)(struct cmdq_cb_data data);
+
+struct cmdq_task_cb {
+ cmdq_async_flush_cb cb;
+ void *data;
+};
+
+struct cmdq_pkt {
+ void *va_base;
+ size_t cmd_buf_size; /* command occupied size */
+ size_t buf_size; /* real buffer size */
+ struct cmdq_task_cb cb;
+};
+
+#endif /* __MTK_CMDQ_MAILBOX_H__ */
--
1.9.1
^ permalink raw reply related
* [PATCH v17 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit
From: HS Liao @ 2016-11-23 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479890343-4979-1-git-send-email-hs.liao@mediatek.com>
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.
Signed-off-by: HS Liao <hs.liao@mediatek.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mailbox/mtk-gce.txt | 43 ++++++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 0000000..d2d3ccb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,43 @@
+MediaTek GCE
+===============
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- #mbox-cells: Should be 2
+
+Required properties for a client device:
+- mboxes: client use mailbox to communicate with GCE, it should have this
+ property and list of phandle, mailbox channel specifiers, and atomic
+ execution flag.
+
+Example:
+
+ gce: gce at 10212000 {
+ compatible = "mediatek,mt8173-gce";
+ reg = <0 0x10212000 0 0x1000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+
+ #mbox-cells = <2>;
+ };
+
+Example for a client device:
+
+ mmsys: clock-controller at 14000000 {
+ compatible = "mediatek,mt8173-mmsys";
+ mboxes = <&gce 0 1 /* main display with atomic execution */
+ &gce 1 1>; /* sub display with atomic execution */
+ ...
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v17 0/4] Mediatek MT8173 CMDQ support
From: HS Liao @ 2016-11-23 8:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.
These patches have a build dependency on top of v4.9-rc1.
Changes since v16:
- merge suspend/resume patch into cmdq driver patch
- merge power saving patch into cmdq driver patch
- split cmdq mailbox controller and cmdq helper into two different patches
Best regards,
HS Liao
HS Liao (4):
dt-bindings: soc: Add documentation for the MediaTek GCE unit
mailbox: mediatek: Add Mediatek CMDQ driver
arm64: dts: mt8173: Add GCE node
soc: mediatek: Add Mediatek CMDQ helper
.../devicetree/bindings/mailbox/mtk-gce.txt | 43 ++
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 10 +
drivers/mailbox/Kconfig | 10 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mtk-cmdq-mailbox.c | 632 +++++++++++++++++++++
drivers/soc/mediatek/Kconfig | 11 +
drivers/soc/mediatek/Makefile | 1 +
drivers/soc/mediatek/mtk-cmdq-helper.c | 310 ++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 75 +++
include/linux/soc/mediatek/mtk-cmdq.h | 174 ++++++
10 files changed, 1268 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
--
1.9.1
^ permalink raw reply
* [PATCH 0/10] mmc: Add support to Marvell Xenon SD Host Controller
From: Gregory CLEMENT @ 2016-11-23 8:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.86006f271b60cf7c0b4c5a51762a9dacca4c4718.1477911954.git-series.gregory.clement@free-electrons.com>
Hi Ulf,
On lun., oct. 31 2016, Gregory CLEMENT <gregory.clement@free-electrons.com> wrote:
> Hello,
>
> This the second version of the series adding support for the SDHCI
> Xenon controller. It can be currently found on the Armada 37xx and the
> Armada 7K/8K but will be also used in more Marvell SoC (and not only
> the mvebu ones actually).
>
> Some of the remarks had been taking into account since the first
> version, according to Ziji Hu, here are the following chcanges:
> "Changes in V2:
> rebase on v4.9-rc2.
> Re-write Xenon bindings. Ajust Xenon DT property naming.
> Add a new DT property to indicate eMMC card type, instead of using
> variable card_candidate.
> Clear quirks SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 in Xenon platform data
> Add support to HS400 retuning."
>
> I think the main open point which remains is about issuing commands
> from the ->set_ios() callback (in patch 7).
> Ulf, could you comment about it?
This part is the last thing missing, we are about to solve the last
issues about the binding, but we still didn't have your opinion about
issuing commands from the ->set_ios() callback and Adrian required it to
take this series.
To have more context you can have a look on:
http://marc.info/?l=linux-mmc&m=147618996414673&w=2
it is the original email where Adrian wanted your agreement.
Thanks,
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 2/4] ARM: dts: davinci: da850: add VPIF
From: Sekhar Nori @ 2016-11-23 8:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7hh96yiwdj.fsf@baylibre.com>
On Wednesday 23 November 2016 11:13 AM, Kevin Hilman wrote:
> David Lechner <david@lechnology.com> writes:
>
>> On 11/22/2016 01:45 PM, Kevin Hilman wrote:
>>> Add VPIF and VPIF capture nodes to da850. VPIF capture has two input
>>> channels describe using the standard DT ports and enpoints.
>>>
>>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>>> ---
>>> arch/arm/boot/dts/da850.dtsi | 28 ++++++++++++++++++++++++++++
>>> 1 file changed, 28 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>>> index 6205917b4f59..e05e2bb834e8 100644
>>> --- a/arch/arm/boot/dts/da850.dtsi
>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>> @@ -453,7 +453,35 @@
>>> interrupts = <52>;
>>> status = "disabled";
>>> };
>>> +
>>> + vpif: video at 0x00217000 {
>>
>> Should be @217000
>>
>>> + compatible = "ti,da850-vpif";
>>> + reg = <0x00217000 0x1000>;
>>
>> Could omit leading 0's to be consistent with existing entries.
>>
>> reg = <0x217000 0x1000>;
>
> Ugh, yeah. I hate that convention, but better to be consistent, I guess.
>
>>> + status = "disabled";
>>> + };
>>> +
>>> + vpif_capture: video-capture at 0x00217000 {
>>
>> Again, @217000. But it seems odd to have two device nodes with the
>> same address. Is enabling these mutually exclusive?
>
> They're not mutually exclusive because the vpif is the one that actually
> maps the register range (since it's shared between vpif_display and
> vpif_capture) so I guess I should just drop the reg property from the
> vpif_capture node.
Reading the documentation, VPIF is presented as a single device, with
two channels dedicated to display and two for capture. Most of the
channel registers are independent, but there are are some like interrupt
enable which are common for all channels. So I believe we cannot use
simple-mfd. But I believe VPIF display and capture should be subdevices
of a single VPIF device.
It should look something like this, I think:
vpif: video at 217000 {
compatible = "ti,da850-vpif";
reg = <0x217000 0x1000>;
interrupts = <92>;
status = "disabled";
vpif_capture: video-capture {
compatible = "ti,da850-vpif-capture"
port {
vpif_ch0: endpoint at 0 {
reg = <0>;
bus-width = <8>;
};
vpif_ch1: endpoint at 1 {
reg = <1>;
bus-width = <8>;
data-shift = <8>;
};
};
};
vpif_display: video-display {
compatible = "ti,da850-vpif-display"
port {
vpif_ch2: endpoint at 2 {
reg = <2>;
bus-width = <8>;
data-shift = <16>;
};
vpif_ch3: endpoint at 3 {
reg = <3>;
bus-width = <8>;
data-shift = <24>;
};
};
};
};
The interrupt too, seems to be common interrupt for both display and
capture. So, it should not be under the capture node. BTW, I am sure
what exactly data-shift is used for. It does not seem to be used in the
driver patches too. I just extrapolated the values based on the pattern
I saw.
Thanks,
Sekhar
^ permalink raw reply
* [GIT PULL] Second Round of Renesas ARM Based SoC Updates for v4.10
From: Geert Uytterhoeven @ 2016-11-23 8:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMimsQphE4TzrJ7EPpp90VQG23vGP3jVrJK3qQrZgNEd3g@mail.gmail.com>
Hi Olof,
On Wed, Nov 23, 2016 at 12:30 AM, Olof Johansson <olof@lixom.net> wrote:
> On Tue, Nov 22, 2016 at 1:56 AM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>> On Mon, Nov 21, 2016 at 5:35 PM, Olof Johansson <olof@lixom.net> wrote:
>>> On Mon, Nov 21, 2016 at 8:27 AM, Geert Uytterhoeven
>>> <geert@linux-m68k.org> wrote:
>>>> On Mon, Nov 21, 2016 at 5:19 PM, Olof Johansson <olof@lixom.net> wrote:
>>>>> On Mon, Nov 21, 2016 at 1:31 AM, Geert Uytterhoeven
>>>>> <geert@linux-m68k.org> wrote:
>>>>>> On Sat, Nov 19, 2016 at 2:28 AM, Olof Johansson <olof@lixom.net> wrote:
>>>>>>> Is there a reason you're adding a config option per SoC?
>>>>>>>
>>>>>>> I think you'd be better off not adding these config options, and just adding
>>>>>>> support for the SoCs through compatibles (and adding the drivers to defconfigs,
>>>>>>> etc).
>>>>>>
>>>>>> Yes there is a reason: kernel size.
>>>>>> The main offenders are the pinctrl tables, which add ca. 20-50 KiB per
>>>>>> supported SoC.
>>>>>
>>>>> So don't turn on that pinctrl driver unless you have that SoC?
>>>>
>>>> The enablement of the pinctrl driver (and the clock driver, FWIW) is controlled
>>>> by the SoC Kconfig symbol. If you want support for the SoC, you want the
>>>> pinctrl driver, too.
>>>
>>> Oh, that's trivial to fix! Do as almost all other SoCs do, and don't
>>> use silent options.
>>
>> What does that gain us? The ability to enable support for an SoC, without
>> enabling the accompanying pinctrl driver, leading to a non-booting system?
>
> It doesn't enable anything new, it just makes it less awkward for you
> to add new SoCs in the future without creating dependencies on new
> Kconfig symbols in the arch directory.
>
>> As soon as you have any pinctrl properties in the DT, you need the pinctrl
>> driver. Unless you disable CONFIG_PINCTRL (it's selected, and not
>> user-controlled), and rely on fragile reset state/boot loader.
>>
>> Pinctrl (and clock and irqchip) on-SoC drivers are special: if you fail to
>> include them, the system won't boot.
>
> This isn't about booting without a pinctrl driver. It's about avoiding
> adding new config symbols when they're not needed.
>
> I started out comparing your way of using config options with, for
> example, Exynos that has a bunch of different SoCs enabled. Having
> dependencies described clearly has some value, since it can be hard to
> know if you can turn off a driver and still have a bootable system
> with some of the other platforms.
>
> That being said, I think you should look at changing how you use your
> config options to make it less messy to add new ones:
[...]
Thanks, I'll have a look to see if we can improve things...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [RFC PATCH] ARM: dts: Add support for Turris Omnia
From: Uwe Kleine-König @ 2016-11-23 8:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479859770-9375-1-git-send-email-tmshlvck@gmail.com>
Hello Tomas,
calling it v4 would be nice.
On Wed, Nov 23, 2016 at 01:09:20AM +0100, Tomas Hlavacek wrote:
> Turris Omnia board by CZ.NIC:
>
> * Marvell Armada 385 SoC
> * 1 or 2 GB DDR3
> * eMMC
> * 8 MB SPI flash (U-Boot and rescue Linux image)
> * 88E1514 PHY
> * 88E6176 Ethernet switch (not supported)
>
> Supported board revision: CZ11NIC13 (production board).
>
> Signed-off-by: Tomas Hlavacek <tmshlvck@gmail.com>
As you picked my v3, you should keep my S-o-b.
> ---
> Changes since Uwe's version:
>
> - add MBUS regions (needed for Marvell CESA)
> - remove rtc disable (WFM with CZ11NIC13 = production board)
If I do
mw 0xf10184a0 0xfd4d4cfa
in the boot loader, it seems to work for me, too. You don't need that?
> - cleanup comments
>
> Unsupported peripherals:
> - MV88E7176 switch
> - SFP
> - LEDs
LEDs is not that bad IMHO, because they work. You just cannot change
their function, but they blink according to their default trigger.
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/armada-385-turris-omnia.dts | 279 ++++++++++++++++++++++++++
> 2 files changed, 280 insertions(+)
> create mode 100644 arch/arm/boot/dts/armada-385-turris-omnia.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index befcd26..f1d3b9ff 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -920,6 +920,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
> armada-385-db-ap.dtb \
> armada-385-linksys-caiman.dtb \
> armada-385-linksys-cobra.dtb \
> + armada-385-turris-omnia.dtb \
> armada-388-clearfog.dtb \
> armada-388-db.dtb \
> armada-388-gp.dtb \
> diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
> new file mode 100644
> index 0000000..5ef3d62
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
> @@ -0,0 +1,279 @@
> +/*
> + * Device Tree file for the Turris Omnia
> + * Schematic available at https://www.turris.cz/doc/_media/rtrom01-schema.pdf
> + *
> + * Copyright (C) 2016 Uwe Kleine-K?nig <uwe@kleine-koenig.org>
> + * Copyright (C) 2016 Tomas Hlavacek <tmshlvkc@gmail.com>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + * a) This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without
> + * any warranty of any kind, whether express or implied.
> + *
> + * Or, alternatively,
> + *
> + * b) Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include "armada-385.dtsi"
> +
> +/ {
> + model = "Turris Omnia";
> + compatible = "cznic,turris-omnia", "marvell,armada385", \
> + "marvell,armada380";
You don't need a \ here AFAIK.
> +
> + chosen {
> + stdout-path = &uart0;
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0x00000000 0x40000000>; /* 1024 MB */
> + };
> +
> + soc {
> + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
> + MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
> + MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
> + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
> +
> + internal-regs {
> +
> + /* USB part of the PCIe2/USB 2.0 port */
> + usb at 58000 {
> + status = "okay";
> + };
> +
> + sata at a8000 {
> + status = "okay";
> + };
> +
> + sdhci at d8000 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&sdhci_pins>;
> + status = "okay";
> +
> + bus-width = <8>;
> + no-1-8-v;
> + non-removable;
> + };
> +
> + usb3 at f0000 {
> + status = "okay";
> + };
> +
> + usb3 at f8000 {
> + status = "okay";
> + };
> + };
> +
> + pcie-controller {
> + status = "okay";
> +
> + pcie at 1,0 {
> + /* Port 0, Lane 0 */
> + status = "okay";
> + };
> +
> + pcie at 2,0 {
> + /* Port 1, Lane 0 */
> + status = "okay";
> + };
> +
> + pcie at 3,0 {
> + /* Port 2, Lane 0 */
> + status = "okay";
> + };
> + };
> + };
> +};
> +
> +/* Connected to 88E6176 switch, port 6 */
> +ð0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&ge0_rgmii_pins>;
> + status = "okay";
> + phy-mode = "rgmii-id";
> +
> + fixed-link {
> + speed = <1000>;
> + full-duplex;
> + };
> +};
> +
> +/* Connected to 88E6176 switch, port 5 */
> +ð1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&ge1_rgmii_pins>;
> + status = "okay";
> + phy-mode = "rgmii-id";
> +
> + fixed-link {
> + speed = <1000>;
> + full-duplex;
> + };
> +};
> +
> +/* WAN port */
> +ð2 {
> + status = "okay";
> + phy-mode = "sgmii";
> + phy = <&phy1>;
> +};
> +
> +&i2c0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c0_pins>;
> + status = "okay";
> +
> + i2cmux at 70 {
> + compatible = "nxp,pca9547";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x70>;
> + status = "okay";
> +
> + i2c at 0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + status = "okay";
> +
> + /* STM32F0 command interface at address 0x2a.
> + * STM32F0 LED interface at address 0x2b.
> + */
Should this better be:
/*
* STM32F0 command interface at address 0x2a.
* STM32F0 LED interface at address 0x2b.
*/
As is recommended for comments in .c?
> +
> + eeprom at 54 {
> + compatible = "at,24c64";
> + reg = <0x54>;
> +
> + /* The EEPROM contains data for bootloader.
> + * Contents:
> + * struct omnia_eeprom {
> + * u32 magic; (=0x0341a034)
> + * u32 ramsize;
ramsize in GiB?
> + * char region[4] (=0x0);
This is for the WLAN regdomain, right?
> + * u32 crc32;
> + * };
> + */
ditto for the comment format.
> + };
> + };
> +
> + /* Channel 1: Routed to PCIe0/mSATA connector (CN7A).
> + * Channel 2: Routed to PCIe1/USB2 connector (CN61A).
> + * Channel 3: Routed to PCIe2 connector (CN62A).
> + * Channel 4: Routed to SFP+.
> + * Channel 5: ATSHA204A at address 0x64.
> + * Channel 6: Routed to user pin header CN11.
> + */
I'd like to keep the busses as Andrew already pointed out. For example
this might make it possible to use i2c-tools to read out the mac address
from the ATSHA.
> + i2c at 7 {
> + /* GPIO expander for SFP+ signals */
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <7>;
> +
> + wangpio: gpio at 71 {
> + compatible = "nxp,pca9538";
> + reg = <0x71>;
> + interrupt-parent = <&gpio1>;
> + interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
> + gpio-controller;
> + #gpio-cells = <2>;
> + };
> + };
> + };
> +};
> +
> +&mdio {
> + pinctrl-names = "default";
> + pinctrl-0 = <&mdio_pins>;
> + status = "okay";
> +
> + phy1: phy at 1 {
> + status = "okay";
> + compatible = "ethernet-phy-id0141.0DD1", \
> + "ethernet-phy-ieee802.3-c22";
Drop the \
> + reg = <1>;
> + /* IRQ is connected to PCA9538 pin 7. Currently it
> + * can not be utilized.
> + */
> + };
> +
> + /* Switch MV88E7176 at address 0x10. */
> +};
> +
> +&pinctrl {
> + spi0cs1_pins: spi0-pins-0cs1 {
> + marvell,pins = "mpp26";
> + marvell,function = "spi0";
> + };
Why did you drop the pcawan pinctrl?
> +};
> +
> +&spi0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&spi0_pins &spi0cs1_pins>;
Oh, this is wrong (already in my patch): this is cs0 not cs1.
> + status = "okay";
> +
> + spi-nor at 0 {
> + compatible = "spansion,s25fl164k", "jedec,spi-nor";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0>;
> + spi-max-frequency = <40000000>;
> +
> + partition at 0 {
> + reg = <0x0 0x00100000>;
> + label = "U-Boot";
> + };
> +
> + partition at 1 {
> + reg = <0x00100000 0x00700000>;
> + label = "Rescue system";
> + };
> + };
> +
> + /* SPI0 + CS1 (MPP26) is routed to a pin header CN11. */
Looks strange. What about
/* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */
Maybe also add the node for this pin to &pinctrl, but don't use it in
&spi0.pinctrl-0? This would nicely document the MPP26 part.
> +};
> +
> +&uart0 {
> + /* Pin header CN10. */
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart0_pins>;
> + status = "okay";
> +};
> +
> +&uart1 {
> + /* Pin header CN11. */
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart1_pins>;
> + status = "okay";
> +};
> +
Trailing new line
Best regards
Uwe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/dac38887/attachment-0001.sig>
^ permalink raw reply
* [PATCH 5/7] add bindings for stm32 IIO timer drivers
From: Benjamin Gaignard @ 2016-11-23 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161122171820.GL10134@dell.home>
If it is ok for you I will add "id" parameter in mfd driver and
forward it to the sub-devices drivers
to be able to distinguish the hardware blocks
2016-11-22 18:18 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 22 Nov 2016, Benjamin Gaignard wrote:
>
>> [snip]
>> >> + "st,stm32-iio-timer5"
>> >> + "st,stm32-iio-timer6"
>> >> + "st,stm32-iio-timer7"
>> >> + "st,stm32-iio-timer8"
>> >> + "st,stm32-iio-timer9"
>> >> + "st,stm32-iio-timer10"
>> >> + "st,stm32-iio-timer11"
>> >> + "st,stm32-iio-timer12"
>> >> + "st,stm32-iio-timer13"
>> >> + "st,stm32-iio-timer14"
>> >
>> > We can't do this. This is a binding for a driver, not for the hardware.
>> >
>>
>> Unfortunately each instance for the hardware IP have little
>> differences like which triggers they could accept or size of the
>> counter register,
>> and I doesn't have value inside the hardware to distinguish them so
>> the only way I found is to use compatible.
>
> Can't you represent these as properties?
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org ? Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
--
Benjamin Gaignard
Graphic Study Group
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 2/2] arm64: Pass RAM boundary and enable-dcache flag to purgatory
From: Pratyush Anand @ 2016-11-23 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123080816.GA30255@verge.net.au>
Hi Simon,
Thanks for your review comment.
On Wed, Nov 23, 2016 at 1:38 PM, Simon Horman <horms@verge.net.au> wrote:
> On Wed, Nov 23, 2016 at 07:41:52AM +0530, Pratyush Anand wrote:
>>
>>
>> On Wednesday 23 November 2016 07:33 AM, Dave Young wrote:
>> >>Although this is very unlikely that a hardware will support only 16K page
>> >>> sizes, however it is possible. Therefore, its better to keep it disabled by
>> >>> default.
>> >If it is *unlikely* it could be better to make it as default and add a
>> >--disable-dcache instead.
>> >
>>
>> I think, I can do that.
>
> Can this be detected at run-time?
Thats doable. OK, so if everyone agrees then I can send a V2 where
neither --enable-dcache nor --disable-dcache will be used. It will
enable dcache if 4K/64K page is supported and will do nothing
otherwise.
~Pratyush
^ permalink raw reply
* [PATCH 1/7] add binding for stm32 multifunctions timer driver
From: Benjamin Gaignard @ 2016-11-23 8:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161122165228.GK10134@dell.home>
2016-11-22 17:52 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 22 Nov 2016, Benjamin Gaignard wrote:
>
>> Add bindings information for stm32 timer MFD
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> ---
>> .../devicetree/bindings/mfd/stm32-timer.txt | 53 ++++++++++++++++++++++
>> 1 file changed, 53 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timer.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/stm32-timer.txt b/Documentation/devicetree/bindings/mfd/stm32-timer.txt
>> new file mode 100644
>> index 0000000..3cefce1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/stm32-timer.txt
>> @@ -0,0 +1,53 @@
>> +STM32 multifunctions timer driver
>
> "STM32 Multi-Function Timer/PWM device bindings"
>
> Doesn't this shared device have a better name?
In SoC documentation those hardware blocks are named "advanced-control
timers", "general purpose timers" or "basic timers"
"stm32-timer" name is already used for clock source driver, that why I
have prefix it with mfd
>
>> +stm32 timer MFD allow to handle at the same time pwm and IIO timer devices
>
> No need for this sentence.
>
OK
>> +Required parameters:
>> +- compatible: must be one of the follow value:
>> + "st,stm32-mfd-timer1"
>> + "st,stm32-mfd-timer2"
>> + "st,stm32-mfd-timer3"
>> + "st,stm32-mfd-timer4"
>> + "st,stm32-mfd-timer5"
>> + "st,stm32-mfd-timer6"
>> + "st,stm32-mfd-timer7"
>> + "st,stm32-mfd-timer8"
>> + "st,stm32-mfd-timer9"
>> + "st,stm32-mfd-timer10"
>> + "st,stm32-mfd-timer11"
>> + "st,stm32-mfd-timer12"
>> + "st,stm32-mfd-timer13"
>> + "st,stm32-mfd-timer14"
>
> We don't normally number devices.
>
> What's stopping you from simply doing:
>
> pwm1: pwm1 at 40010000 {
> compatible = "st,stm32-pwm";
> };
> pwm2: pwm1 at 40020000 {
> compatible = "st,stm32-pwm";
> };
> pwm3: pwm1 at 40030000 {
> compatible = "st,stm32-pwm";
> };
>
Because each instance of the hardware is slightly different: number of
pwm channels, triggers capabilities, etc ..
so I need to distinguish them.
Since it look to be a problem I will follow your suggestion and add a
property this driver to be able to identify each instance.
Do you think that "id" parameter (integer for 1 to 14) is acceptable ?
>> +- reg : Physical base address and length of the controller's
>> + registers.
>> +- clock-names: Set to "mfd_timer_clk".
>
Only one but I use devm_regmap_init_mmio_clk() to avoid calling
clk_{enable/disable}
everywhere in the drivers when reading/writing regsister.
devm_regmap_init_mmio_clk() find the clock by it name that why I have
put it here
In the doc this clock in named "clk_int" I will use this name.
> How many clocks are there?
>
> If only 1, you don't need this property.
>
> "mfd_timer_clk" is not the correct name.
>
> What is it called in the datasheet?
>
>> +- clocks: Phandle of the clock used by the timer module.
>
> "Phandle to the clock ..."
>
>> + For Clk properties, please refer to [1].
>> +- interrupts : Reference to the timer interrupt
>
> Reference to?
>
> See how other binding documents describe this property.
>
>> +Optional parameters:
>> +- resets : Reference to a reset controller asserting the timer
>
> As above.
>
>> +Optional subnodes:
>
> Either use ":" or " :" or "<tab>:", but keep it consistent.
>
>> +- pwm: See Documentation/devicetree/bindings/pwm/pwm-stm32.txt
>> +- iiotimer: See Documentation/devicetree/bindings/iio/timer/stm32-iio-timer.txt
>> +
>> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
>
> Use the relative paths "../clock/", "../pwm/", "../iio/".
>
OK
>> +Example:
>> + mfd_timer1: mfdtimer1 at 40010000 {
>
> This is not an "MFD timer". MFD is a Linuxisum.
>
>> + compatible = "st,stm32-mfd-timer1";
>
> Better description required.
>
>> + reg = <0x40010000 0x400>;
>> + clocks = <&rcc 0 160>;
>> + clock-names = "mfd_timer_clk";
>> + interrupts = <27>;
>> +
>> + pwm1: pwm1 at 40010000 {
>> + compatible = "st,stm32-pwm1";
>> + };
>> +
>> + iiotimer1: iiotimer1 at 40010000 {
>> + compatible = "st,stm32-iio-timer1";
>> + };
>> + };
^ permalink raw reply
* [PATCH v2 1/3] arm64: dts: add USB1-related nodes of Allwinner A64
From: Maxime Ripard @ 2016-11-23 8:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161122155831.8724-1-icenowy@aosc.xyz>
On Tue, Nov 22, 2016 at 11:58:29PM +0800, Icenowy Zheng wrote:
> Allwinner A64 have two HCI USB controllers, a OTG controller and a USB
> PHY device which have two ports. One of the port is wired to both a HCI
> USB controller and the OTG controller, which is currently not supported.
> The another one is only wired to a HCI controller, and the device node of
> OHCI/EHCI controller of the port can be added now.
>
> Also the A64 USB PHY device node is also added for the HCI controllers to
> work.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> ---
> Changes since v1:
> - Remove manual CLK_USB_OHCI0 gate, as it's dealed by ccu driver now.
> - Sort the nodes and fixed {e,o}hci1 regs.
> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 44 +++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 3d70be3..2572dd6 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -122,6 +122,50 @@
> #size-cells = <1>;
> ranges;
>
> + usbphy: phy at 01c19400 {
> + compatible = "allwinner,sun50i-a64-usb-phy";
> + reg = <0x01c19400 0x14>,
> + <0x01c1b800 0x4>;
> + reg-names = "phy_ctrl",
> + "pmu1";
> + clocks = <&ccu CLK_USB_PHY0>,
> + <&ccu CLK_USB_PHY1>;
> + clock-names = "usb0_phy",
> + "usb1_phy";
> + resets = <&ccu RST_USB_PHY0>,
> + <&ccu RST_USB_PHY1>;
> + reset-names = "usb0_reset",
> + "usb1_reset";
> + status = "disabled";
> + #phy-cells = <1>;
> + };
> +
> + ohci1: usb at 01c1b400 {
> + compatible = "allwinner,sun50i-a64-ohci", "generic-ohci";
> + reg = <0x01c1b400 0x100>;
> + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&ccu CLK_BUS_OHCI1>,
> + <&ccu CLK_USB_OHCI1>;
> + resets = <&ccu RST_BUS_OHCI1>;
> + phys = <&usbphy 1>;
> + phy-names = "usb";
> + status = "disabled";
> + };
> +
> + ehci1: usb at 01c1b000 {
> + compatible = "allwinner,sun50i-a64-ehci", "generic-ehci";
> + reg = <0x01c1b000 0x100>;
> + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&ccu CLK_BUS_OHCI1>,
> + <&ccu CLK_BUS_EHCI1>,
> + <&ccu CLK_USB_OHCI1>;
> + resets = <&ccu RST_BUS_OHCI1>,
> + <&ccu RST_BUS_EHCI1>;
> + phys = <&usbphy 1>;
> + phy-names = "usb";
> + status = "disabled";
> + };
The nodes were inverted, also, please use "arm64: dts: allwinner:" for
your prefix in the future.
I fixed both issues and queued for 4.11.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/63204017/attachment-0001.sig>
^ permalink raw reply
* [PATCH 2/2] arm64: Pass RAM boundary and enable-dcache flag to purgatory
From: Simon Horman @ 2016-11-23 8:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <81975e6e-b97a-0401-0e18-b2d26722c1dd@redhat.com>
On Wed, Nov 23, 2016 at 07:41:52AM +0530, Pratyush Anand wrote:
>
>
> On Wednesday 23 November 2016 07:33 AM, Dave Young wrote:
> >>Although this is very unlikely that a hardware will support only 16K page
> >>> sizes, however it is possible. Therefore, its better to keep it disabled by
> >>> default.
> >If it is *unlikely* it could be better to make it as default and add a
> >--disable-dcache instead.
> >
>
> I think, I can do that.
Can this be detected at run-time?
It sounds like it will be painful if on some setups the default
doesn't work.
^ permalink raw reply
* [RFC V2: PATCH 2/2] reset: hisilicon: add reset-hi3660
From: Zhangfei Gao @ 2016-11-23 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479888476-13138-1-git-send-email-zhangfei.gao@linaro.org>
Add hi3660 reset driver
Reset offset & bits should be listed in dts
Like:
iomcu_rst: iomcu_rst_controller {
compatible = "hisilicon,hi3660-reset";
#reset-cells = <1>;
hisi,rst-syscon = <&iomcu>;
hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
0x20 0x10 /* 1: i2c1 */
0x20 0x20 /* 2: i2c2 */
0x20 0x8000000>; /* 3: i2c6 */
};
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
---
drivers/reset/hisilicon/Kconfig | 7 ++
drivers/reset/hisilicon/Makefile | 1 +
drivers/reset/hisilicon/reset-hi3660.c | 144 +++++++++++++++++++++++++++++++++
3 files changed, 152 insertions(+)
create mode 100644 drivers/reset/hisilicon/reset-hi3660.c
diff --git a/drivers/reset/hisilicon/Kconfig b/drivers/reset/hisilicon/Kconfig
index 1ff8b0c..10134dc 100644
--- a/drivers/reset/hisilicon/Kconfig
+++ b/drivers/reset/hisilicon/Kconfig
@@ -1,3 +1,10 @@
+config COMMON_RESET_HI3660
+ tristate "Hi3660 Reset Driver"
+ depends on ARCH_HISI || COMPILE_TEST
+ default ARCH_HISI
+ help
+ Build the Hisilicon Hi3660 reset driver.
+
config COMMON_RESET_HI6220
tristate "Hi6220 Reset Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile
index c932f86..ab8a7bf 100644
--- a/drivers/reset/hisilicon/Makefile
+++ b/drivers/reset/hisilicon/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o
+obj-$(CONFIG_COMMON_RESET_HI3660) += reset-hi3660.o
diff --git a/drivers/reset/hisilicon/reset-hi3660.c b/drivers/reset/hisilicon/reset-hi3660.c
new file mode 100644
index 0000000..3307252
--- /dev/null
+++ b/drivers/reset/hisilicon/reset-hi3660.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016-2017 Linaro Ltd.
+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+struct hi3660_reset_data {
+ unsigned int off;
+ unsigned int bits;
+};
+
+struct hi3660_reset_controller {
+ struct reset_controller_dev rst;
+ struct regmap *map;
+ const struct hi3660_reset_data *datas;
+};
+
+#define to_hi3660_reset_controller(_rst) \
+ container_of(_rst, struct hi3660_reset_controller, rst)
+
+static int hi3660_reset_program_hw(struct reset_controller_dev *rcdev,
+ unsigned long idx, bool assert)
+{
+ struct hi3660_reset_controller *rc = to_hi3660_reset_controller(rcdev);
+ const struct hi3660_reset_data *d;
+
+ if (idx >= rcdev->nr_resets)
+ return -EINVAL;
+
+ d = &rc->datas[idx];
+
+ if (assert)
+ return regmap_write(rc->map, d->off, d->bits);
+ else
+ return regmap_write(rc->map, d->off + 4, d->bits);
+}
+
+static int hi3660_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ return hi3660_reset_program_hw(rcdev, idx, true);
+}
+
+static int hi3660_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ return hi3660_reset_program_hw(rcdev, idx, false);
+}
+
+static int hi3660_reset_dev(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ int err;
+
+ err = hi3660_reset_assert(rcdev, idx);
+ if (err)
+ return err;
+
+ return hi3660_reset_deassert(rcdev, idx);
+}
+
+static struct reset_control_ops hi3660_reset_ops = {
+ .reset = hi3660_reset_dev,
+ .assert = hi3660_reset_assert,
+ .deassert = hi3660_reset_deassert,
+};
+
+static int hi3660_reset_probe(struct platform_device *pdev)
+{
+ struct hi3660_reset_controller *rc;
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct hi3660_reset_data *datas;
+ const __be32 *list;
+ int size, nr, i;
+
+ rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
+ if (!rc)
+ return -ENOMEM;
+
+ rc->map = syscon_regmap_lookup_by_phandle(np, "hisi,rst-syscon");
+ if (IS_ERR(rc->map)) {
+ dev_err(dev, "failed to get hi3660,rst-syscon\n");
+ return PTR_ERR(rc->map);
+ }
+
+ list = of_get_property(np, "hisi,reset-bits", &size);
+ if (!list || (size / sizeof(*list)) % 2 != 0) {
+ dev_err(dev, "invalid DT reset description\n");
+ return -EINVAL;
+ }
+
+ nr = (size / sizeof(*list)) / 2;
+ datas = devm_kzalloc(dev, nr * sizeof(*datas), GFP_KERNEL);
+ if (!datas)
+ return -ENOMEM;
+
+ for (i = 0; i < nr; i++) {
+ datas[i].off = be32_to_cpup(list++);
+ datas[i].bits = be32_to_cpup(list++);
+ }
+
+ rc->rst.ops = &hi3660_reset_ops,
+ rc->rst.of_node = np;
+ rc->rst.nr_resets = nr;
+ rc->datas = datas;
+
+ return reset_controller_register(&rc->rst);
+}
+
+static const struct of_device_id hi3660_reset_match[] = {
+ { .compatible = "hisilicon,hi3660-reset", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, hi3660_reset_match);
+
+static struct platform_driver hi3660_reset_driver = {
+ .probe = hi3660_reset_probe,
+ .driver = {
+ .name = "hi3660-reset",
+ .of_match_table = hi3660_reset_match,
+ },
+};
+
+static int __init hi3660_reset_init(void)
+{
+ return platform_driver_register(&hi3660_reset_driver);
+}
+arch_initcall(hi3660_reset_init);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:hi3660-reset");
+MODULE_DESCRIPTION("HiSilicon Hi3660 Reset Driver");
--
2.7.4
^ permalink raw reply related
* [RFC v2: PATCH 1/2] dt-bindings: Document the hi3660 reset bindings
From: Zhangfei Gao @ 2016-11-23 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479888476-13138-1-git-send-email-zhangfei.gao@linaro.org>
Add DT bindings documentation for hi3660 SoC reset controller.
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
---
.../bindings/reset/hisilicon,hi3660-reset.txt | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
new file mode 100644
index 0000000..250daf2
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
@@ -0,0 +1,51 @@
+Hisilicon System Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+The reset controller registers are part of the system-ctl block on
+hi3660 SoC.
+
+Required properties:
+- compatible: should be
+ "hisilicon,hi3660-reset"
+- #reset-cells: 1, see below
+- hisi,rst-syscon: phandle of the reset's syscon.
+- hisi,reset-bits: Contains the reset control register information
+ Should contain 2 cells for each reset exposed to
+ consumers, defined as:
+ Cell #1 : offset from the syscon register base
+ Cell #2 : bits position of the control register
+
+Example:
+ iomcu: iomcu at ffd7e000 {
+ compatible = "hisilicon,hi3660-iomcu", "syscon";
+ reg = <0x0 0xffd7e000 0x0 0x1000>;
+ };
+
+ iomcu_rst: iomcu_rst_controller {
+ compatible = "hisilicon,hi3660-reset";
+ #reset-cells = <1>;
+ hisi,rst-syscon = <&iomcu>;
+ hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
+ 0x20 0x10 /* 1: i2c1 */
+ 0x20 0x20 /* 2: i2c2 */
+ 0x20 0x8000000>; /* 3: i2c6 */
+ };
+
+Specifying reset lines connected to IP modules
+==============================================
+example:
+
+ i2c0: i2c at ..... {
+ ...
+ resets = <&iomcu_rst 0>;
+ ...
+ };
+
+ i2c1: i2c at ..... {
+ ...
+ resets = <&iomcu_rst 1>;
+ ...
+ };
--
2.7.4
^ permalink raw reply related
* [RFC V2:PATCH 0/2] add reset-hi3660
From: Zhangfei Gao @ 2016-11-23 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Arnd Bergmann <arnd@arndb.de>
Considering Arnd and Philipp suggestions,
move reset register to dts as table instead of dts header in case of ABI issue
Zhangfei Gao (2):
dt-bindings: Document the hi3660 reset bindings
reset: hisilicon: add reset-hi3660
.../bindings/reset/hisilicon,hi3660-reset.txt | 51 ++++++++
drivers/reset/hisilicon/Kconfig | 7 +
drivers/reset/hisilicon/Makefile | 1 +
drivers/reset/hisilicon/reset-hi3660.c | 144 +++++++++++++++++++++
4 files changed, 203 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
create mode 100644 drivers/reset/hisilicon/reset-hi3660.c
--
2.7.4
^ permalink raw reply
* [PATCH] ARM: dts: sunxi: Enable UEXT related nodes for Olimex A20 SOM EVB
From: Maxime Ripard @ 2016-11-23 8:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121164911.76900-1-manu@bidouilliste.com>
On Mon, Nov 21, 2016 at 05:49:11PM +0100, Emmanuel Vadot wrote:
> UEXT are Universal EXTension connector from Olimex. They embed i2c, spi
> and uart pins along power in one connector and are found on most,
> if not all, Olimex boards.
> The Olimex A20 SOM EVB have two UEXT connector so enable the nodes found on
> those two connectors.
>
> Signed-off-by: Emmanuel Vadot <manu@bidouilliste.com>
Fixed the indentation of the spi pinctrl cells, and applied.
Please note that I'm note planning to send any new pull request, so
this will likely end up in 4.11.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/ada4f4d4/attachment-0001.sig>
^ permalink raw reply
* Synopsys Ethernet QoS Driver
From: Giuseppe CAVALLARO @ 2016-11-23 8:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1806171479803900@web16j.yandex.ru>
Hello Ozgur
On 11/22/2016 9:38 AM, Ozgur Karatas wrote:
> Hello all,
>
> I think, ethtool and mdio don't work because the tool's not support to "QoS", right?
>
> Maybe, need a new API. I'm looking for dwceqos code but "tc" tools is very idea.
>
> I hope to be me always helpful.
tools work but indeed should be extended to support more for QoS.
This is another task we have to keep in mind, well spot.
Peppe
>
> Regards,
>
> Ozgur
>
> 21.11.2016, 16:38, "Giuseppe CAVALLARO" <peppe.cavallaro@st.com>:
>> Hello Joao
>>
>> On 11/21/2016 2:48 PM, Joao Pinto wrote:
>>> Synopsys QoS IP is a separated hardware component, so it should be reusable by
>>> all implementations using it and so have its own "core driver" and platform +
>>> pci glue drivers. This is necessary for example in hardware validation, where
>>> you prototype an IP and instantiate its drivers and test it.
>>>
>>> Was there a strong reason to integrate QoS features directly in stmmac and not
>>> in synopsys/dwc_eth_qos.*?
>>
>> We decided to enhance the stmmac on supporting the QoS for several
>> reasons; for example the common APIs that the driver already exposed and
>> actually suitable for other SYNP chips. Then, PTP, EEE,
>> S/RGMII, MMC could be shared among different chips with a minimal
>> effort. This meant a lot of code already ready.
>>
>> For sure, the net-core, Ethtool, mdio parts were reused. Same for the
>> glue logic files.
>> For the latter, this helped to easily bring-up new platforms also
>> because the stmmac uses the HW cap register to auto-configure many
>> parts of the MAC core, DMA and modules. This helped many users, AFAIK.
>>
>> For validation purpose, this is my experience, the stmmac helped
>> a lot because people used the same code to validate different HW
>> and it was easy to switch to a platform to another one in order to
>> verify / check if the support was ok or if a regression was introduced.
>> This is important for complex supports like PTP or EEE.
>>
>> Hoping this can help.
>>
>> Do not hesitate to contact me for further details
>>
>> peppe
>
^ permalink raw reply
* [PATCH 3/6] reset: hisilicon: add reset-hi3660
From: zhangfei @ 2016-11-23 8:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479810156.13701.1.camel@pengutronix.de>
Hi, Philipp
On 2016?11?22? 18:22, Philipp Zabel wrote:
> Am Dienstag, den 22.11.2016, 10:42 +0100 schrieb Arnd Bergmann:
>> On Tuesday, November 22, 2016 5:34:05 PM CET zhangfei wrote:
>>> On 2016?11?22? 16:50, Arnd Bergmann wrote:
>>>> On Tuesday, November 22, 2016 3:49:18 PM CET Zhangfei Gao wrote:
>>>>> +static const struct hisi_reset_channel_data hi3660_iomcu_rst[] = {
>>>>> + [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3),
>>>>> + [HI3660_RST_I2C1] = HISI_RST_SEP(0x20, 4),
>>>>> + [HI3660_RST_I2C2] = HISI_RST_SEP(0x20, 5),
>>>>> + [HI3660_RST_I2C6] = HISI_RST_SEP(0x20, 27),
>>>>> +};
>>>>> +
>>>>> +static struct hisi_reset_controller_data hi3660_iomcu_controller = {
>>>>> + .nr_channels = ARRAY_SIZE(hi3660_iomcu_rst),
>>>>> + .channels = hi3660_iomcu_rst,
>>>>> +};
>>>>> +
>>>>> +static const struct hisi_reset_channel_data hi3660_crgctrl_rst[] = {
>>>>> + [HI3660_RST_I2C3] = HISI_RST_SEP(0x78, 7),
>>>>> + [HI3660_RST_I2C4] = HISI_RST_SEP(0x78, 27),
>>>>> + [HI3660_RST_I2C7] = HISI_RST_SEP(0x60, 14),
>>>>> + [HI3660_RST_SD] = HISI_RST_SEP(0x90, 18),
>>>>> + [HI3660_RST_SDIO] = HISI_RST_SEP(0x90, 20),
>>>>> + [HI3660_RST_UFS] = HISI_RST_SEP(0x84, 12),
>>>>> + [HI3660_RST_UFS_ASSERT] = HISI_RST_SEP(0x84, 7),
>>>>> + [HI3660_RST_PCIE_SYS] = HISI_RST_SEP(0x84, 26),
>>>>> + [HI3660_RST_PCIE_PHY] = HISI_RST_SEP(0x84, 27),
>>>>> + [HI3660_RST_PCIE_BUS] = HISI_RST_SEP(0x84, 31),
>>>>> + [HI3660_RST_USB3OTG_PHY] = HISI_RST_SEP(0x90, 3),
>>>>> + [HI3660_RST_USB3OTG] = HISI_RST_SEP(0x90, 5),
>>>>> + [HI3660_RST_USB3OTG_32K] = HISI_RST_SEP(0x90, 6),
>>>>> + [HI3660_RST_USB3OTG_AHB] = HISI_RST_SEP(0x90, 7),
>>>>> + [HI3660_RST_USB3OTG_MUX] = HISI_RST_SEP(0x90, 8),
>>>>> +};
>>>> I think you can avoid the trap of the ABI incompatibility if
>>>> you just define those as in the binding as tuples, using #reset-cells=2.
>>>>
>>>> In particular for the first set, it seems really silly to redefine
>>>> the numbers when there is just a simple integer number.
>>> Could you clarify more, still not understand.
>>> The number is index of the arrays, and the index will be used in dts.
>>> The arrays lists the registers offset and bit shift.
>>> For example:
>>>
>>> [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3), means register offset : 0x20, and bit shift = 3.
>>>
>>> And Documentation/devicetree/bindings/reset/reset.txt
>>> Required properties:
>>> #reset-cells: Number of cells in a reset specifier; Typically 0 for nodes
>>> with a single reset output and 1 for nodes with multiple
>>> reset outputs.
> This is just a suggestion, for reset controllers where the reset lines
> can reasonably be enumerated by a single integer. If there is a good
> reason to use more complicated bindings, more cells can be used.
> That being said, I dislike having to spread register/bit information
> throughout the device trees at the consumer/phandle sites, if the
> register/bit information absolutely has to be put into the device tree,
> I'd prefer a binding similar to ti-syscon, where it's all in one place.
Thanks for the suggestion.
Will use table in dts instead of
include/dt-bindings/reset/hisi,hi3660-resets.h
like
+ hisi,reset-bits = <0x20 0x8 /* 0: i2c0 */
+ 0x20 0x10 /* 1: i2c1 */
+ 0x20 0x20 /* 2: i2c2 */
+ 0x20 0x8000000>; /* 3: i2c6 */
To remove the potential ABI issue as pointed by Arnd.
>
>> You can easily enumerate the registers that contain reset bits here,
>> so just use one cell for the register and another one for the index.
> Changing the reset cells is an incompatible change, and this is not a
> straight forward register/bit mapping in hardware either. There are
> currently three registers involved: enable (+0x0), disable (+0x4), and
> status (+0x8). Also, what if in the future one of these reset bits have
> to be handled inverted (as just happened for hi3519)?
Discussed with Jianchen, we are only considering Kirin series now.
The inverted in hi3519 is only for some line, not the whole controller.
It is more like a bug and kirin does not have such issue.
Will send a new RFC, help take a look.
Thanks
^ permalink raw reply
* [PATCH 3/3] ARM: dts: sunxi: enable SDIO Wi-Fi on Orange Pi Zero
From: Maxime Ripard @ 2016-11-23 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121162421.800-3-icenowy@aosc.xyz>
Hi,
On Tue, Nov 22, 2016 at 12:24:21AM +0800, Icenowy Zheng wrote:
> There's a Allwinner's XR819 SDIO Wi-Fi module soldered on the board of
> Orange Pi Zero, which used a dedicated regulator to power.
>
> Add the device tree node of the regulator, the enable gpio (with
> mmc-pwrseq) and the sdio controller.
>
> There's a out-of-tree driver tested to work with this device tree.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> ---
> New patch in the patchset, since a out-of-tree working xradio driver is done.
>
> If there is any problem in this patch, it can be omitted.
No particular problem with this one, however it can and should be
merged with the previous one.
Minor comments below though.
>
> arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts | 42 ++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
> index b428e47..39cac26 100644
> --- a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
> +++ b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
> @@ -79,6 +79,24 @@
> gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
> };
> };
> +
> + reg_vcc_wifi: reg_vcc_wifi {
> + compatible = "regulator-fixed";
> + pinctrl-names = "default";
> + pinctrl-0 = <&vcc_wifi_pin_opi0>;
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-name = "vcc-wifi";
> + enable-active-high;
> + gpio = <&pio 0 20 GPIO_ACTIVE_HIGH>;
> + };
> +
> + wifi_pwrseq: wifi_pwrseq {
> + compatible = "mmc-pwrseq-simple";
> + pinctrl-names = "default";
> + pinctrl-0 = <&wifi_pwrseq_pin_opi0>;
> + reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
> + };
> };
>
> &ehci1 {
> @@ -95,6 +113,20 @@
> status = "okay";
> };
>
> +&mmc1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&mmc1_pins_a>;
> + vmmc-supply = <®_vcc_wifi>;
> + mmc-pwrseq = <&wifi_pwrseq>;
> + bus-width = <4>;
> + non-removable;
> + status = "okay";
> +};
> +
> +&mmc1_pins_a {
> + allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
This should be bias-pull-up.
> +};
> +
> &ohci1 {
> status = "okay";
> };
> @@ -104,6 +136,11 @@
> pins = "PA17";
> function = "gpio_out";
> };
> +
> + vcc_wifi_pin_opi0: vcc_wifi_pin at 0 {
> + allwinner,pins = "PA20";
This should be pins
> + allwinner,function = "gpio_out";
This should be function
> + };
> };
>
> &r_pio {
> @@ -111,6 +148,11 @@
> pins = "PL10";
> function = "gpio_out";
> };
> +
> + wifi_pwrseq_pin_opi0: wifi_pwrseq_pin at 0 {
> + allwinner,pins = "PL7";
> + allwinner,function = "gpio_out";
And same thing here.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/d0892fbe/attachment.sig>
^ permalink raw reply
* [PATCH v2 2/3] ARM: dts: sunxi: add support for Orange Pi Zero board
From: Maxime Ripard @ 2016-11-23 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121162421.800-2-icenowy@aosc.xyz>
On Tue, Nov 22, 2016 at 12:24:20AM +0800, Icenowy Zheng wrote:
> Orange Pi Zero is a board that came with the new Allwinner H2+ SoC.
>
> Add a device tree file for it.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> ---
> Changes since v2:
> - Use generic pinconf binding instead of legacy allwinner pinctrl binding.
> - removed uart3, which is not accessible on Orange Pi Zero.
> - Removed sun8i-h2plus.dtsi and make Orange Pi Zero dts directly include
> sun8i-h3.dtsi.
> - Removed allwinner,sun8i-h3 compatible.
>
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts | 137 +++++++++++++++++++++++
Ditto, h2-plus-orangepi-zero.
> 2 files changed, 138 insertions(+)
> create mode 100644 arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 802a10d..51a1dd7 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -834,6 +834,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
> sun8i-a33-sinlinx-sina33.dtb \
> sun8i-a83t-allwinner-h8homlet-v2.dtb \
> sun8i-a83t-cubietruck-plus.dtb \
> + sun8i-h2plus-orangepi-zero.dtb \
> sun8i-h3-bananapi-m2-plus.dtb \
> sun8i-h3-nanopi-neo.dtb \
> sun8i-h3-orangepi-2.dtb \
> diff --git a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
> new file mode 100644
> index 0000000..b428e47
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
> @@ -0,0 +1,137 @@
> +/*
> + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
> + *
> + * Based on sun8i-h3-orangepi-one.dts, which is:
> + * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + * a) This file is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License, or (at your option) any later version.
> + *
> + * This file is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + * b) Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +#include "sun8i-h3.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/sun4i-a10.h>
> +
> +/ {
> + model = "Xunlong Orange Pi Zero";
> + compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2plus";
> +
> + aliases {
> + serial0 = &uart0;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> + pinctrl-names = "default";
> + pinctrl-0 = <&leds_opi0>, <&leds_r_opi0>;
> +
> + pwr_led {
> + label = "orangepi:green:pwr";
> + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
> + default-state = "on";
> + };
> +
> + status_led {
> + label = "orangepi:red:status";
> + gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
> + };
> + };
> +};
> +
> +&ehci1 {
> + status = "okay";
> +};
> +
> +&mmc0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
> + vmmc-supply = <®_vcc3v3>;
> + bus-width = <4>;
> + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
> + cd-inverted;
> + status = "okay";
> +};
> +
> +&ohci1 {
> + status = "okay";
> +};
> +
> +&pio {
> + leds_opi0: led_pins at 0 {
> + pins = "PA17";
> + function = "gpio_out";
> + };
> +};
> +
> +&r_pio {
> + leds_r_opi0: led_pins at 0 {
> + pins = "PL10";
> + function = "gpio_out";
> + };
> +};
> +
> +&uart0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart0_pins_a>;
> + status = "okay";
> +};
> +
> +&uart1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart1_pins>;
> + status = "disabled";
> +};
> +
> +&uart2 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart2_pins>;
> + status = "disabled";
> +};
I'm not sure you answered me on this one. Are those exposed on the
headers? why did you put them as disabled here?
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/8430f549/attachment.sig>
^ permalink raw reply
* [PATCH v2 1/3] ARM: sunxi: add support for H2+ SoC
From: Maxime Ripard @ 2016-11-23 7:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121162421.800-1-icenowy@aosc.xyz>
Hi,
On Tue, Nov 22, 2016 at 12:24:19AM +0800, Icenowy Zheng wrote:
> Allwinner H2+ is a quad-core Cortex-A7 SoC.
>
> It is very like H3, that they share the same SoC ID (0x1680), and H3
> memory maps as well as drivers works well on the SoC.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> ---
> Documentation/arm/sunxi/README | 4 ++++
> Documentation/devicetree/bindings/arm/sunxi.txt | 1 +
> arch/arm/mach-sunxi/sunxi.c | 1 +
> 3 files changed, 6 insertions(+)
>
> diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
> index cd02433..1fe4d99c 100644
> --- a/Documentation/arm/sunxi/README
> +++ b/Documentation/arm/sunxi/README
> @@ -63,6 +63,10 @@ SunXi family
> + User Manual
> http://dl.linux-sunxi.org/A33/A33%20user%20manual%20release%201.1.pdf
>
> + - Allwinner H2+ (sun8i)
> + + No document available now, but is known to be working properly with
> + H3 drivers and memory map.
> +
I'm not sure the phrasing is right here. I would prefer something like:
"No document publicly available now, but looks very similar to the H3"
> - Allwinner H3 (sun8i)
> + Datasheet
> http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt
> index 4d6467c..26b35a7 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.txt
> +++ b/Documentation/devicetree/bindings/arm/sunxi.txt
> @@ -13,6 +13,7 @@ using one of the following compatible strings:
> allwinner,sun8i-a33
> allwinner,sun8i-a83t
> allwinner,sun8i-h3
> + allwinner,sun8i-h2plus
h2-plus please.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/57bf0c4d/attachment.sig>
^ permalink raw reply
* [PATCH 1/3] of: base: add support to get machine compatible string
From: Sekhar Nori @ 2016-11-23 7:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fdb93150-9089-c7bb-2b0a-21ded241a647@arm.com>
On Tuesday 22 November 2016 09:16 PM, Sudeep Holla wrote:
> Hi Sekhar,
>
> On 22/11/16 15:06, Sekhar Nori wrote:
>> Hi Sudeep,
>>
>> On Tuesday 22 November 2016 04:23 PM, Sudeep Holla wrote:
>>>
>>>
>>> On 22/11/16 10:41, Bartosz Golaszewski wrote:
>>>> Add a function allowing to retrieve the compatible string of the root
>>>> node of the device tree.
>>>>
>>>
>>> Rob has queued [1] and it's in -next today. You can reuse that if you
>>> are planning to target this for v4.11 or just use open coding in your
>>> driver for v4.10 and target this move for v4.11 to avoid cross tree
>>> dependencies as I already mentioned in your previous thread.
>>
>> I dont have your original patch in my mailbox, but I wonder if
>> returning a pointer to property string for a node whose reference has
>> already been released is safe to do? Probably not an issue for the root
>> node, but still feels counter-intuitive.
>>
>
> I am not sure if I understand the issue here. Are you referring a case
> where of_root is freed ?
Yes, right, thats what I was hinting at. Since you are giving up the
reference to the device node before the function returns, the user can
be left with a dangling reference.
> Also I have seen drivers today just using this pointer directly, but
> it's better to copy the string(I just saw this done in one case)
Hmm, the reference is given up before the API returns, so I doubt
copying it later is any additional benefit.
I suspect this is a theoretical issue though since root device node is
probably never freed.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH] PCI: Add information about describing PCI in ACPI
From: Ard Biesheuvel @ 2016-11-23 7:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123010600.GF4832@bhelgaas-glaptop.roam.corp.google.com>
On 23 November 2016 at 01:06, Bjorn Helgaas <helgaas@kernel.org> wrote:
> On Tue, Nov 22, 2016 at 10:09:50AM +0000, Ard Biesheuvel wrote:
>> On 17 November 2016 at 17:59, Bjorn Helgaas <bhelgaas@google.com> wrote:
>
>> > +PCI host bridges are PNP0A03 or PNP0A08 devices. Their _CRS should
>> > +describe all the address space they consume. In principle, this would
>> > +be all the windows they forward down to the PCI bus, as well as the
>> > +bridge registers themselves. The bridge registers include things like
>> > +secondary/subordinate bus registers that determine the bus range below
>> > +the bridge, window registers that describe the apertures, etc. These
>> > +are all device-specific, non-architected things, so the only way a
>> > +PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which
>> > +contain the device-specific details. These bridge registers also
>> > +include ECAM space, since it is consumed by the bridge.
>> > +
>> > +ACPI defined a Producer/Consumer bit that was intended to distinguish
>> > +the bridge apertures from the bridge registers [4, 5]. However,
>> > +BIOSes didn't use that bit correctly, and the result is that OSes have
>> > +to assume that everything in a PCI host bridge _CRS is a window. That
>> > +leaves no way to describe the bridge registers in the PNP0A03/PNP0A08
>> > +device itself.
>>
>> Is that universally true? Or is it still possible to do the right
>> thing here on new ACPI architectures such as arm64?
>
> That's a very good question. I had thought that the ACPI spec had
> given up on Consumer/Producer completely, but I was wrong. In the 6.0
> spec, the Consumer/Producer bit is still documented in the Extended
> Address Space Descriptor (sec 6.4.3.5.4). It is documented as
> "ignored" in the QWord, DWord, and Word descriptors (sec 6.4.3.5.1,2,3).
>
> Linux looks at the producer_consumer bit in acpi_decode_space(), which
> I think is used for all these descriptors (QWord, DWord, Word, and
> Extended). This doesn't quite follow the spec -- we probably should
> ignore it except for Extended. In any event, acpi_decode_space() sets
> IORESOURCE_WINDOW for Producer descriptors, but we don't test
> IORESOURCE_WINDOW in the PCI host bridge code.
>
> x86 and ia64 supply their own pci_acpi_root_prepare_resources()
> functions that call acpi_pci_probe_root_resources(), which parses _CRS
> and looks at producer_consumer. Then they do a little arch-specific
> stuff on the result.
>
> On arm64 we use acpi_pci_probe_root_resources() directly, with no
> arch-specific stuff.
>
> On all three arches, we ignore the Consumer/Producer bit, so all the
> resources are treated as Producers, e.g., as bridge windows.
>
> I think we *could* implement an arm64 version of
> pci_acpi_root_prepare_resources() that would pay attention to the
> Consumer/Producer bit by checking IORESOURCE_WINDOW. To be spec
> compliant, we would have to use Extended descriptors for all bridge
> windows, even if they would fit in a DWord or QWord.
>
> Should we do that? I dunno. I'd like to hear your opinion(s).
>
Yes, I think we should. If the spec allows for a way for a PNP0A03
device to describe all of its resources unambiguously, we should not
be relying on workarounds that were designed for another architecture
in another decade (for, presumably, another OS)
Just for my understanding, we will need to use extended descriptors
for all consumed *and* produced regions, even though dword/qword are
implicitly produced-only, due to the fact that the bit is ignored?
> It *would* be nice to have bridge registers in the bridge _CRS. That
> would eliminate the need for looking up the HISI0081/PNP0C02 devices
> to find the bridge registers. Avoiding that lookup is only a
> temporary advantage -- the next round of bridges are supposed to fully
> implement ECAM, and then we won't need to know where the registers
> are.
>
> Apart from the lookup, there's still some advantage in describing the
> registers in the PNP0A03 device instead of an unrelated PNP0C02
> device, because it makes /proc/iomem more accurate and potentially
> makes host bridge hotplug cleaner. We would have to enhance the host
> bridge driver to do the reservations currently done by pnp/system.c.
>
> There's some value in doing it the same way as on x86, even though
> that way is somewhat broken.
>
> Whatever we decide, I think it's very important to get it figured out
> ASAP because it affects the ECAM quirks that we're trying to merge in
> v4.10.
>
I agree. What exactly is the impact for the quirks mechanism as proposed?
^ permalink raw reply
* [PATCH v2] clk: qoriq: added ls1012a clock configuration
From: Scott Wood @ 2016-11-23 7:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479802499-9083-1-git-send-email-yuantian.tang@nxp.com>
On 11/22/2016 02:28 AM, yuantian.tang at nxp.com wrote:
> From: Tang Yuantian <Yuantian.Tang@nxp.com>
>
> Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
> ---
> v2:
> - remove commit message as it is duplicated to title
>
> drivers/clk/clk-qoriq.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
> index 1bece0f..65c21d7 100644
> --- a/drivers/clk/clk-qoriq.c
> +++ b/drivers/clk/clk-qoriq.c
> @@ -202,6 +202,14 @@ static const struct clockgen_muxinfo ls1021a_cmux = {
> }
> };
>
> +static const struct clockgen_muxinfo ls1012a_cmux = {
> + {
> + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
> + {},
> + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
> + }
> +};
> +
> static const struct clockgen_muxinfo t1040_cmux = {
> {
> [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
> @@ -482,6 +490,16 @@ static const struct clockgen_chipinfo chipinfo[] = {
> .pll_mask = 0x03,
> },
> {
> + .compat = "fsl,ls1012a-clockgen",
> + .cmux_groups = {
> + &ls1012a_cmux
> + },
> + .cmux_to_group = {
> + 0, -1
> + },
> + .pll_mask = 0x03,
> + },
> + {
> .compat = "fsl,ls1043a-clockgen",
> .init_periph = t2080_init_periph,
> .cmux_groups = {
> @@ -1282,6 +1300,7 @@ static void __init clockgen_init(struct device_node *np)
> CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
> +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
> CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
Again, can you please keep the chip lists sorted? ls1012a doesn't go
after ls1021a.
-Scott
^ 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