* [arm-platforms:irq/alloc_fwnode_pa 7/8] drivers/pci/controller/pci-hyperv.c:2593:27: error: passing argument 2 of 'kasprintf' from incompatible pointer type
From: kbuild test robot @ 2019-08-07 12:51 UTC (permalink / raw)
To: Marc Zyngier; +Cc: kbuild-all, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 6477 bytes --]
tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/alloc_fwnode_pa
head: d5865f5879f6f9e9653b5f2256dcf41059301d56
commit: 58266b4ea93f578ca3838bf04b92e51b4a7496f9 [7/8] PCI: hv: Allocate a named fwnode instead of an address-based one
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
reproduce:
git checkout 58266b4ea93f578ca3838bf04b92e51b4a7496f9
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
drivers/pci/controller/pci-hyperv.c: In function 'hv_pci_probe':
>> drivers/pci/controller/pci-hyperv.c:2593:19: warning: passing argument 1 of 'kasprintf' makes integer from pointer without a cast [-Wint-conversion]
name = kasprintf("%pUL", &hdev->dev_instance);
^~~~~~
In file included from drivers/pci/controller/pci-hyperv.c:40:0:
include/linux/kernel.h:466:7: note: expected 'gfp_t {aka unsigned int}' but argument is of type 'char *'
char *kasprintf(gfp_t gfp, const char *fmt, ...);
^~~~~~~~~
>> drivers/pci/controller/pci-hyperv.c:2593:27: error: passing argument 2 of 'kasprintf' from incompatible pointer type [-Werror=incompatible-pointer-types]
name = kasprintf("%pUL", &hdev->dev_instance);
^
In file included from drivers/pci/controller/pci-hyperv.c:40:0:
include/linux/kernel.h:466:7: note: expected 'const char *' but argument is of type 'guid_t * {aka struct <anonymous> *}'
char *kasprintf(gfp_t gfp, const char *fmt, ...);
^~~~~~~~~
cc1: some warnings being treated as errors
vim +/kasprintf +2593 drivers/pci/controller/pci-hyperv.c
2512
2513 /**
2514 * hv_pci_probe() - New VMBus channel probe, for a root PCI bus
2515 * @hdev: VMBus's tracking struct for this root PCI bus
2516 * @dev_id: Identifies the device itself
2517 *
2518 * Return: 0 on success, -errno on failure
2519 */
2520 static int hv_pci_probe(struct hv_device *hdev,
2521 const struct hv_vmbus_device_id *dev_id)
2522 {
2523 struct hv_pcibus_device *hbus;
2524 char *name;
2525 int ret;
2526
2527 /*
2528 * hv_pcibus_device contains the hypercall arguments for retargeting in
2529 * hv_irq_unmask(). Those must not cross a page boundary.
2530 */
2531 BUILD_BUG_ON(sizeof(*hbus) > PAGE_SIZE);
2532
2533 hbus = (struct hv_pcibus_device *)get_zeroed_page(GFP_KERNEL);
2534 if (!hbus)
2535 return -ENOMEM;
2536 hbus->state = hv_pcibus_init;
2537
2538 /*
2539 * The PCI bus "domain" is what is called "segment" in ACPI and
2540 * other specs. Pull it from the instance ID, to get something
2541 * unique. Bytes 8 and 9 are what is used in Windows guests, so
2542 * do the same thing for consistency. Note that, since this code
2543 * only runs in a Hyper-V VM, Hyper-V can (and does) guarantee
2544 * that (1) the only domain in use for something that looks like
2545 * a physical PCI bus (which is actually emulated by the
2546 * hypervisor) is domain 0 and (2) there will be no overlap
2547 * between domains derived from these instance IDs in the same
2548 * VM.
2549 */
2550 hbus->sysdata.domain = hdev->dev_instance.b[9] |
2551 hdev->dev_instance.b[8] << 8;
2552
2553 hbus->hdev = hdev;
2554 refcount_set(&hbus->remove_lock, 1);
2555 INIT_LIST_HEAD(&hbus->children);
2556 INIT_LIST_HEAD(&hbus->dr_list);
2557 INIT_LIST_HEAD(&hbus->resources_for_children);
2558 spin_lock_init(&hbus->config_lock);
2559 spin_lock_init(&hbus->device_list_lock);
2560 spin_lock_init(&hbus->retarget_msi_interrupt_lock);
2561 init_completion(&hbus->remove_event);
2562 hbus->wq = alloc_ordered_workqueue("hv_pci_%x", 0,
2563 hbus->sysdata.domain);
2564 if (!hbus->wq) {
2565 ret = -ENOMEM;
2566 goto free_bus;
2567 }
2568
2569 ret = vmbus_open(hdev->channel, pci_ring_size, pci_ring_size, NULL, 0,
2570 hv_pci_onchannelcallback, hbus);
2571 if (ret)
2572 goto destroy_wq;
2573
2574 hv_set_drvdata(hdev, hbus);
2575
2576 ret = hv_pci_protocol_negotiation(hdev);
2577 if (ret)
2578 goto close;
2579
2580 ret = hv_allocate_config_window(hbus);
2581 if (ret)
2582 goto close;
2583
2584 hbus->cfg_addr = ioremap(hbus->mem_config->start,
2585 PCI_CONFIG_MMIO_LENGTH);
2586 if (!hbus->cfg_addr) {
2587 dev_err(&hdev->device,
2588 "Unable to map a virtual address for config space\n");
2589 ret = -ENOMEM;
2590 goto free_config;
2591 }
2592
> 2593 name = kasprintf("%pUL", &hdev->dev_instance);
2594 if (!name) {
2595 ret = -ENOMEM;
2596 goto unmap;
2597 }
2598
2599 hbus->sysdata.fwnode = irq_domain_alloc_named_fwnode(name);
2600 kfree(name);
2601 if (!hbus->sysdata.fwnode) {
2602 ret = -ENOMEM;
2603 goto unmap;
2604 }
2605
2606 ret = hv_pcie_init_irq_domain(hbus);
2607 if (ret)
2608 goto free_fwnode;
2609
2610 ret = hv_pci_query_relations(hdev);
2611 if (ret)
2612 goto free_irq_domain;
2613
2614 ret = hv_pci_enter_d0(hdev);
2615 if (ret)
2616 goto free_irq_domain;
2617
2618 ret = hv_pci_allocate_bridge_windows(hbus);
2619 if (ret)
2620 goto free_irq_domain;
2621
2622 ret = hv_send_resources_allocated(hdev);
2623 if (ret)
2624 goto free_windows;
2625
2626 prepopulate_bars(hbus);
2627
2628 hbus->state = hv_pcibus_probed;
2629
2630 ret = create_root_hv_pci_bus(hbus);
2631 if (ret)
2632 goto free_windows;
2633
2634 return 0;
2635
2636 free_windows:
2637 hv_pci_free_bridge_windows(hbus);
2638 free_irq_domain:
2639 irq_domain_remove(hbus->irq_domain);
2640 free_fwnode:
2641 irq_domain_free_fwnode(hbus->sysdata.fwnode);
2642 unmap:
2643 iounmap(hbus->cfg_addr);
2644 free_config:
2645 hv_free_config_window(hbus);
2646 close:
2647 vmbus_close(hdev->channel);
2648 destroy_wq:
2649 destroy_workqueue(hbus->wq);
2650 free_bus:
2651 free_page((unsigned long)hbus);
2652 return ret;
2653 }
2654
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70149 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v10 20/22] x86: mm: Convert dump_pagetables to use walk_page_range
From: Steven Price @ 2019-08-07 12:58 UTC (permalink / raw)
To: Andrew Morton
Cc: Mark Rutland, Dave Hansen, Arnd Bergmann, Ard Biesheuvel,
Peter Zijlstra, Catalin Marinas, x86, linux-kernel, linux-mm,
Jérôme Glisse, Ingo Molnar, Borislav Petkov,
Andy Lutomirski, H. Peter Anvin, James Morse, Thomas Gleixner,
Will Deacon, linux-arm-kernel, Liang, Kan
In-Reply-To: <20190806165823.3f735b45a7c4163aca20a767@linux-foundation.org>
On 07/08/2019 00:58, Andrew Morton wrote:
> On Wed, 31 Jul 2019 16:46:01 +0100 Steven Price <steven.price@arm.com> wrote:
>
>> Make use of the new functionality in walk_page_range to remove the
>> arch page walking code and use the generic code to walk the page tables.
>>
>> The effective permissions are passed down the chain using new fields
>> in struct pg_state.
>>
>> The KASAN optimisation is implemented by including test_p?d callbacks
>> which can decide to skip an entire tree of entries
>>
>> ...
>>
>> +static const struct ptdump_range ptdump_ranges[] = {
>> +#ifdef CONFIG_X86_64
>>
>> -#define pgd_large(a) (pgtable_l5_enabled() ? pgd_large(a) : p4d_large(__p4d(pgd_val(a))))
>> -#define pgd_none(a) (pgtable_l5_enabled() ? pgd_none(a) : p4d_none(__p4d(pgd_val(a))))
>> +#define normalize_addr_shift (64 - (__VIRTUAL_MASK_SHIFT + 1))
>> +#define normalize_addr(u) ((signed long)(u << normalize_addr_shift) \
>> + >> normalize_addr_shift)
>>
>> -static inline bool is_hypervisor_range(int idx)
>> -{
>> -#ifdef CONFIG_X86_64
>> - /*
>> - * A hole in the beginning of kernel address space reserved
>> - * for a hypervisor.
>> - */
>> - return (idx >= pgd_index(GUARD_HOLE_BASE_ADDR)) &&
>> - (idx < pgd_index(GUARD_HOLE_END_ADDR));
>> + {0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2},
>> + {normalize_addr(PTRS_PER_PGD * PGD_LEVEL_MULT / 2), ~0UL},
>
> This blows up because PGD_LEVEL_MULT is sometimes not a constant.
>
> x86_64 allmodconfig:
>
> In file included from ./arch/x86/include/asm/pgtable_types.h:249:0,
> from ./arch/x86/include/asm/paravirt_types.h:45,
> from ./arch/x86/include/asm/ptrace.h:94,
> from ./arch/x86/include/asm/math_emu.h:5,
> from ./arch/x86/include/asm/processor.h:12,
> from ./arch/x86/include/asm/cpufeature.h:5,
> from ./arch/x86/include/asm/thread_info.h:53,
> from ./include/linux/thread_info.h:38,
> from ./arch/x86/include/asm/preempt.h:7,
> from ./include/linux/preempt.h:78,
> from ./include/linux/spinlock.h:51,
> from ./include/linux/wait.h:9,
> from ./include/linux/wait_bit.h:8,
> from ./include/linux/fs.h:6,
> from ./include/linux/debugfs.h:15,
> from arch/x86/mm/dump_pagetables.c:11:
> ./arch/x86/include/asm/pgtable_64_types.h:56:22: error: initializer element is not constant
> #define PTRS_PER_PGD 512
> ^
This is very unhelpful of GCC - it's actually PTRS_PER_P4D which isn't
constant!
> arch/x86/mm/dump_pagetables.c:363:6: note: in expansion of macro ‘PTRS_PER_PGD’
> {0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2},
> ^~~~~~~~~~~~
> ./arch/x86/include/asm/pgtable_64_types.h:56:22: note: (near initialization for ‘ptdump_ranges[0].end’)
> #define PTRS_PER_PGD 512
> ^
> arch/x86/mm/dump_pagetables.c:363:6: note: in expansion of macro ‘PTRS_PER_PGD’
> {0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2},
> ^~~~~~~~~~~~
> arch/x86/mm/dump_pagetables.c:360:27: error: initializer element is not constant
> #define normalize_addr(u) ((signed long)(u << normalize_addr_shift) \
> ^
> arch/x86/mm/dump_pagetables.c:364:3: note: in expansion of macro ‘normalize_addr’
> {normalize_addr(PTRS_PER_PGD * PGD_LEVEL_MULT / 2), ~0UL},
> ^~~~~~~~~~~~~~
> arch/x86/mm/dump_pagetables.c:360:27: note: (near initialization for ‘ptdump_ranges[1].start’)
> #define normalize_addr(u) ((signed long)(u << normalize_addr_shift) \
> ^
> arch/x86/mm/dump_pagetables.c:364:3: note: in expansion of macro ‘normalize_addr’
> {normalize_addr(PTRS_PER_PGD * PGD_LEVEL_MULT / 2), ~0UL},
>
> I don't know what to do about this so I'll drop the series.
My best solution to this is to simply make ptdump_ranges dynamic (see
below). But there are other problems with this series (thanks for
spotting them), so I'll send out another version later.
Thanks,
Steve
----8<-----
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 998c7f46763c..8fc129ff985e 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -353,7 +353,10 @@ static void note_page(struct ptdump_state *pt_st,
unsigned long addr, int level,
}
}
-static const struct ptdump_range ptdump_ranges[] = {
+static void ptdump_walk_pgd_level_core(struct seq_file *m, struct
mm_struct *mm,
+ bool checkwx, bool dmesg)
+{
+ const struct ptdump_range ptdump_ranges[] = {
#ifdef CONFIG_X86_64
#define normalize_addr_shift (64 - (__VIRTUAL_MASK_SHIFT + 1))
@@ -368,9 +371,6 @@ static const struct ptdump_range ptdump_ranges[] = {
{0, 0}
};
-static void ptdump_walk_pgd_level_core(struct seq_file *m, struct
mm_struct *mm,
- bool checkwx, bool dmesg)
-{
struct pg_state st = {
.ptdump = {
.note_page = note_page,
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Mark Brown @ 2019-08-07 12:59 UTC (permalink / raw)
To: Koenig, Christian
Cc: kernel-build-reports@lists.linaro.org, Zhou1, Tao,
amd-gfx@lists.freedesktop.org, Christoph Hellwig,
linux-next@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Deucher, Alexander, akpm@linux-foundation.org, Li, Dennis,
Zhang, Hawking
In-Reply-To: <18cd9fa5-2d87-2f41-b5fa-927b9790287d@amd.com>
[-- Attachment #1.1: Type: text/plain, Size: 315 bytes --]
On Wed, Aug 07, 2019 at 10:55:01AM +0000, Koenig, Christian wrote:
> Am 07.08.19 um 12:41 schrieb Christoph Hellwig:
> > writeq/readq are provided whenever the CPU actually supports 64-bit
> > atomic loads and stores.
> Is there a config option which we can make the driver depend on?
64BIT should do the trick.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Christoph Hellwig @ 2019-08-07 13:00 UTC (permalink / raw)
To: Koenig, Christian
Cc: linux-arm-kernel@lists.infradead.org,
kernel-build-reports@lists.linaro.org, Zhou1, Tao,
amd-gfx@lists.freedesktop.org, Christoph Hellwig,
broonie@kernel.org, linux-next@vger.kernel.org,
Deucher, Alexander, akpm@linux-foundation.org, Li, Dennis,
Zhang, Hawking
In-Reply-To: <18cd9fa5-2d87-2f41-b5fa-927b9790287d@amd.com>
On Wed, Aug 07, 2019 at 10:55:01AM +0000, Koenig, Christian wrote:
> >> Essentially writeq/readq doesn't seems to be available on all
> >> architectures either.
> > writeq/readq are provided whenever the CPU actually supports 64-bit
> > atomic loads and stores.
>
> Is there a config option which we can make the driver depend on?
>
> I mean that ARM doesn't support 64bit atomic loads and stores on MMIO is
> quite a boomer for us.
The model is to cheack if readq/writeq are defined, and if not to
include the one of io-64-nonatomic-hi-lo.h or io-64-nonatomic-lo-hi.h.
The reason for that is that hardware is supposed to be able to deal with
two 32-bit writes, but it depends on the hardware if the lower or upper
half is what commits the write.
The only 32-bit platform that claims support for readq/writeq is sh,
and I have doubts if that actually works as expected.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Koenig, Christian @ 2019-08-07 13:00 UTC (permalink / raw)
To: Mark Brown
Cc: kernel-build-reports@lists.linaro.org, Zhou1, Tao,
amd-gfx@lists.freedesktop.org, Christoph Hellwig,
linux-next@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Deucher, Alexander, akpm@linux-foundation.org, Li, Dennis,
Zhang, Hawking
In-Reply-To: <20190807125928.GC4048@sirena.co.uk>
Am 07.08.19 um 14:59 schrieb Mark Brown:
> On Wed, Aug 07, 2019 at 10:55:01AM +0000, Koenig, Christian wrote:
>> Am 07.08.19 um 12:41 schrieb Christoph Hellwig:
>>> writeq/readq are provided whenever the CPU actually supports 64-bit
>>> atomic loads and stores.
>> Is there a config option which we can make the driver depend on?
> 64BIT should do the trick.
That doesn't work because 32bit x86 does support writeq/readq as far as
I know.
Christian.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] firmware: arm_scmi: Use {get,put}_unaligned_le32 accessors
From: Sudeep Holla @ 2019-08-07 13:00 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-kernel, Philipp Zabel, Sudeep Holla
Instead of type-casting the {tx,rx}.buf all over the place while
accessing them to read/write __le32 from/to the firmware, let's use
the nice existing {get,put}_unaligned_le32 accessors to hide all the
type cast ugliness.
Suggested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/firmware/arm_scmi/base.c | 2 +-
drivers/firmware/arm_scmi/clock.c | 10 ++++------
drivers/firmware/arm_scmi/common.h | 2 ++
drivers/firmware/arm_scmi/perf.c | 8 ++++----
drivers/firmware/arm_scmi/power.c | 6 +++---
drivers/firmware/arm_scmi/reset.c | 2 +-
drivers/firmware/arm_scmi/sensors.c | 12 +++++-------
7 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 204390297f4b..f804e8af6521 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -204,7 +204,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(id);
+ put_unaligned_le32(id, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (!ret)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 4a32ae1822a3..199a668ea885 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -107,7 +107,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+ put_unaligned_le32(clk_id, t->tx.buf);
attr = t->rx.buf;
ret = scmi_do_xfer(handle, t);
@@ -204,14 +204,12 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+ put_unaligned_le32(clk_id, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (!ret) {
- __le32 *pval = t->rx.buf;
-
- *value = le32_to_cpu(*pval);
- *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
+ *value = get_unaligned_le32(t->rx.buf);
+ *value |= (u64)get_unaligned_le32(t->rx.buf + 1) << 32;
}
scmi_xfer_put(handle, t);
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 43884e4ceac5..5237c2ff79fe 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -15,6 +15,8 @@
#include <linux/scmi_protocol.h>
#include <linux/types.h>
+#include <asm/unaligned.h>
+
#define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0)
#define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16)
#define PROTOCOL_REV_MAJOR(x) (u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index fb7f6cab2c11..9b338e66a24e 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -195,7 +195,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
attr = t->rx.buf;
ret = scmi_do_xfer(handle, t);
@@ -380,7 +380,7 @@ static int scmi_perf_mb_limits_get(const struct scmi_handle *handle, u32 domain,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (!ret) {
@@ -459,11 +459,11 @@ static int scmi_perf_mb_level_get(const struct scmi_handle *handle, u32 domain,
return ret;
t->hdr.poll_completion = poll;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (!ret)
- *level = le32_to_cpu(*(__le32 *)t->rx.buf);
+ *level = get_unaligned_le32(t->rx.buf);
scmi_xfer_put(handle, t);
return ret;
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c
index 62f3401a1f01..5abef7079c0a 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -96,7 +96,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
attr = t->rx.buf;
ret = scmi_do_xfer(handle, t);
@@ -147,11 +147,11 @@ scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (!ret)
- *state = le32_to_cpu(*(__le32 *)t->rx.buf);
+ *state = get_unaligned_le32(t->rx.buf);
scmi_xfer_put(handle, t);
return ret;
diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
index 11cb8b5ccf34..c1d67a2af12f 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -88,7 +88,7 @@ scmi_reset_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
if (ret)
return ret;
- *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+ put_unaligned_le32(domain, t->tx.buf);
attr = t->rx.buf;
ret = scmi_do_xfer(handle, t);
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
index 7570308a16a0..5b330619a025 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -120,7 +120,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
do {
/* Set the number of sensors to be skipped/already read */
- *(__le32 *)t->tx.buf = cpu_to_le32(desc_index);
+ put_unaligned_le32(desc_index, t->tx.buf);
ret = scmi_do_xfer(handle, t);
if (ret)
@@ -217,7 +217,6 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
u32 sensor_id, u64 *value)
{
int ret;
- __le32 *pval;
struct scmi_xfer *t;
struct scmi_msg_sensor_reading_get *sensor;
struct sensors_info *si = handle->sensor_priv;
@@ -229,7 +228,6 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
if (ret)
return ret;
- pval = t->rx.buf;
sensor = t->tx.buf;
sensor->id = cpu_to_le32(sensor_id);
@@ -237,15 +235,15 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
ret = scmi_do_xfer_with_response(handle, t);
if (!ret) {
- *value = le32_to_cpu(*(pval + 1));
- *value |= (u64)le32_to_cpu(*(pval + 2)) << 32;
+ *value = get_unaligned_le32(t->rx.buf + 1);
+ *value |= (u64)get_unaligned_le32(t->rx.buf + 2) << 32;
}
} else {
sensor->flags = cpu_to_le32(0);
ret = scmi_do_xfer(handle, t);
if (!ret) {
- *value = le32_to_cpu(*pval);
- *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
+ *value = get_unaligned_le32(t->rx.buf);
+ *value |= (u64)get_unaligned_le32(t->rx.buf + 1) << 32;
}
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] arm64: Disable big endian builds with clang
From: Mark Rutland @ 2019-08-07 13:01 UTC (permalink / raw)
To: Mark Brown
Cc: Tri Vo, Catalin Marinas, Nick Desaulniers, clang-built-linux,
Nathan Chancellor, Will Deacon, linux-arm-kernel
In-Reply-To: <20190806183918.41078-1-broonie@kernel.org>
On Tue, Aug 06, 2019 at 07:39:18PM +0100, Mark Brown wrote:
> Current boot tests with clang built big endian kernels in KernelCI are
> showing problems with the kernel being unable to interpret big endian
> userspace. This is a bug and should be fixed but for now let's prevent
> these kernels being built, we may end up needing to add a version
> dependency on the compiler anyway.
>
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>
> The clang people (CCed) are aware and looking into this.
Judging by the kernel log linked in a reply, this is with:
* clang version 8.0.1-svn359952-1~exp1~20190504004501.65 (branches/release_80)
Is that the llvm.org binary release, or a custom build of clang?
* Linux 5.3.0-rc2-next-20190730
Could we previously build a BE kernel with clang? If so, what's the
last working kernel?
Thanks,
Mark.
>
> arch/arm64/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 990fdcbf05c7..1c32d9889e0f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -813,6 +813,7 @@ config ARM64_PA_BITS
>
> config CPU_BIG_ENDIAN
> bool "Build big-endian kernel"
> + depends on !CC_IS_CLANG
> help
> Say Y if you plan on running a kernel in big-endian mode.
>
> --
> 2.20.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Koenig, Christian @ 2019-08-07 13:03 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-arm-kernel@lists.infradead.org,
kernel-build-reports@lists.linaro.org, Zhou1, Tao,
amd-gfx@lists.freedesktop.org, broonie@kernel.org,
linux-next@vger.kernel.org, Deucher, Alexander,
akpm@linux-foundation.org, Li, Dennis, Zhang, Hawking
In-Reply-To: <20190807130043.GA6023@infradead.org>
Am 07.08.19 um 15:00 schrieb Christoph Hellwig:
> On Wed, Aug 07, 2019 at 10:55:01AM +0000, Koenig, Christian wrote:
>>>> Essentially writeq/readq doesn't seems to be available on all
>>>> architectures either.
>>> writeq/readq are provided whenever the CPU actually supports 64-bit
>>> atomic loads and stores.
>> Is there a config option which we can make the driver depend on?
>>
>> I mean that ARM doesn't support 64bit atomic loads and stores on MMIO is
>> quite a boomer for us.
> The model is to cheack if readq/writeq are defined, and if not to
> include the one of io-64-nonatomic-hi-lo.h or io-64-nonatomic-lo-hi.h.
> The reason for that is that hardware is supposed to be able to deal with
> two 32-bit writes, but it depends on the hardware if the lower or upper
> half is what commits the write.
Read, but as I understood Tao change this is not the case here.
Otherwise we would just use our WREG32/RREG32 macros in the driver.
Tao, please explain why exactly we need the WREG64/RREG64 change which
caused this.
Christian.
>
> The only 32-bit platform that claims support for readq/writeq is sh,
> and I have doubts if that actually works as expected.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: Disable big endian builds with clang
From: Mark Brown @ 2019-08-07 13:05 UTC (permalink / raw)
To: Mark Rutland
Cc: Tri Vo, Catalin Marinas, Nick Desaulniers, clang-built-linux,
Nathan Chancellor, Will Deacon, linux-arm-kernel
In-Reply-To: <20190807130111.GE54191@lakrids.cambridge.arm.com>
[-- Attachment #1.1: Type: text/plain, Size: 709 bytes --]
On Wed, Aug 07, 2019 at 02:01:11PM +0100, Mark Rutland wrote:
> On Tue, Aug 06, 2019 at 07:39:18PM +0100, Mark Brown wrote:
> Judging by the kernel log linked in a reply, this is with:
> * clang version 8.0.1-svn359952-1~exp1~20190504004501.65 (branches/release_80)
> Is that the llvm.org binary release, or a custom build of clang?
It's from a llvm.org .deb.
> * Linux 5.3.0-rc2-next-20190730
> Could we previously build a BE kernel with clang? If so, what's the
> last working kernel?
As far as I know this has been broken for as long as we tried building
and booting big endian kernels in clang. The compile works fine, it's
just that the resulting binary doesn't seem to be working so well.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: replace readq/writeq with atomic64 operations
From: Christoph Hellwig @ 2019-08-07 13:07 UTC (permalink / raw)
To: Koenig, Christian
Cc: linux-arm-kernel@lists.infradead.org,
kernel-build-reports@lists.linaro.org, Zhou1, Tao,
amd-gfx@lists.freedesktop.org, Christoph Hellwig, Mark Brown,
linux-next@vger.kernel.org, Deucher, Alexander,
akpm@linux-foundation.org, Li, Dennis, Zhang, Hawking
In-Reply-To: <461cd4e8-31b8-def3-ca92-5b33db8d5621@amd.com>
On Wed, Aug 07, 2019 at 01:00:48PM +0000, Koenig, Christian wrote:
> Am 07.08.19 um 14:59 schrieb Mark Brown:
> > On Wed, Aug 07, 2019 at 10:55:01AM +0000, Koenig, Christian wrote:
> >> Am 07.08.19 um 12:41 schrieb Christoph Hellwig:
> >>> writeq/readq are provided whenever the CPU actually supports 64-bit
> >>> atomic loads and stores.
> >> Is there a config option which we can make the driver depend on?
> > 64BIT should do the trick.
>
> That doesn't work because 32bit x86 does support writeq/readq as far as
> I know.
I also had a vague memory that x86-32 did support it with SSE, but
I can't actually find any traces of that support.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 04/14] media: rkisp1: add Rockchip MIPI Synopsys DPHY driver
From: Sakari Ailus @ 2019-08-07 13:05 UTC (permalink / raw)
To: Helen Koike
Cc: devicetree, eddie.cai.linux, kernel, heiko, jacob2.chen,
jeffy.chen, zyc, linux-kernel, tfiga, linux-rockchip,
hans.verkuil, laurent.pinchart, sakari.ailus, zhengsq, mchehab,
ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <20190730184256.30338-5-helen.koike@collabora.com>
Hi Helen,
Thanks for the patchset.
On Tue, Jul 30, 2019 at 03:42:46PM -0300, Helen Koike wrote:
> From: Jacob Chen <jacob2.chen@rock-chips.com>
>
> This commit adds a subdev driver for Rockchip MIPI Synopsys DPHY driver
>
> Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
> Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com>
> Signed-off-by: Tomasz Figa <tfiga@chromium.org>
> [migrate to phy framework]
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> [update for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.com>
>
> ---
>
> Changes in v8:
> - Remove boiler plate license text
>
> Changes in v7:
> - Migrate dphy specific code from
> drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
> to drivers/phy/rockchip/phy-rockchip-dphy.c
> - Drop support for rk3288
> - Drop support for dphy txrx
> - code styling and checkpatch fixes
>
> drivers/phy/rockchip/Kconfig | 8 +
> drivers/phy/rockchip/Makefile | 1 +
> drivers/phy/rockchip/phy-rockchip-dphy.c | 408 +++++++++++++++++++++++
> 3 files changed, 417 insertions(+)
> create mode 100644 drivers/phy/rockchip/phy-rockchip-dphy.c
>
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index c454c90cd99e..afd072f135e6 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -9,6 +9,14 @@ config PHY_ROCKCHIP_DP
> help
> Enable this to support the Rockchip Display Port PHY.
>
> +config PHY_ROCKCHIP_DPHY
> + tristate "Rockchip MIPI Synopsys DPHY driver"
> + depends on ARCH_ROCKCHIP && OF
How about (...) || COMPILE_TEST ?
> + select GENERIC_PHY_MIPI_DPHY
> + select GENERIC_PHY
> + help
> + Enable this to support the Rockchip MIPI Synopsys DPHY.
> +
> config PHY_ROCKCHIP_EMMC
> tristate "Rockchip EMMC PHY Driver"
> depends on ARCH_ROCKCHIP && OF
> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> index fd21cbaf40dd..f62e9010bcaf 100644
> --- a/drivers/phy/rockchip/Makefile
> +++ b/drivers/phy/rockchip/Makefile
> @@ -1,5 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
> +obj-$(CONFIG_PHY_ROCKCHIP_DPHY) += phy-rockchip-dphy.o
> obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
> obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
> diff --git a/drivers/phy/rockchip/phy-rockchip-dphy.c b/drivers/phy/rockchip/phy-rockchip-dphy.c
> new file mode 100644
> index 000000000000..3a29976c2dff
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-dphy.c
> @@ -0,0 +1,408 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Rockchip MIPI Synopsys DPHY driver
> + *
> + * Based on:
> + *
> + * Copyright (C) 2016 FuZhou Rockchip Co., Ltd.
> + * Author: Yakir Yang <ykk@@rock-chips.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/phy/phy.h>
> +#include <linux/phy/phy-mipi-dphy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define RK3399_GRF_SOC_CON9 0x6224
> +#define RK3399_GRF_SOC_CON21 0x6254
> +#define RK3399_GRF_SOC_CON22 0x6258
> +#define RK3399_GRF_SOC_CON23 0x625c
> +#define RK3399_GRF_SOC_CON24 0x6260
> +#define RK3399_GRF_SOC_CON25 0x6264
> +#define RK3399_GRF_SOC_STATUS1 0xe2a4
> +
> +#define CLOCK_LANE_HS_RX_CONTROL 0x34
> +#define LANE0_HS_RX_CONTROL 0x44
> +#define LANE1_HS_RX_CONTROL 0x54
> +#define LANE2_HS_RX_CONTROL 0x84
> +#define LANE3_HS_RX_CONTROL 0x94
> +#define HS_RX_DATA_LANES_THS_SETTLE_CONTROL 0x75
> +
> +#define MAX_DPHY_CLK 8
> +
> +#define PHY_TESTEN_ADDR (0x1 << 16)
> +#define PHY_TESTEN_DATA (0x0 << 16)
> +#define PHY_TESTCLK (0x1 << 1)
> +#define PHY_TESTCLR (0x1 << 0)
> +#define THS_SETTLE_COUNTER_THRESHOLD 0x04
> +
> +#define HIWORD_UPDATE(val, mask, shift) \
> + ((val) << (shift) | (mask) << ((shift) + 16))
> +
> +#define GRF_SOC_CON12 0x0274
> +
> +#define GRF_EDP_REF_CLK_SEL_INTER_HIWORD_MASK BIT(20)
> +#define GRF_EDP_REF_CLK_SEL_INTER BIT(4)
> +
> +#define GRF_EDP_PHY_SIDDQ_HIWORD_MASK BIT(21)
> +#define GRF_EDP_PHY_SIDDQ_ON 0
> +#define GRF_EDP_PHY_SIDDQ_OFF BIT(5)
> +
> +struct hsfreq_range {
> + u32 range_h;
> + u8 cfg_bit;
> +};
> +
> +static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
> + { 89, 0x00}, { 99, 0x10}, { 109, 0x20}, { 129, 0x01},
> + { 139, 0x11}, { 149, 0x21}, { 169, 0x02}, { 179, 0x12},
> + { 199, 0x22}, { 219, 0x03}, { 239, 0x13}, { 249, 0x23},
> + { 269, 0x04}, { 299, 0x14}, { 329, 0x05}, { 359, 0x15},
> + { 399, 0x25}, { 449, 0x06}, { 499, 0x16}, { 549, 0x07},
> + { 599, 0x17}, { 649, 0x08}, { 699, 0x18}, { 749, 0x09},
> + { 799, 0x19}, { 849, 0x29}, { 899, 0x39}, { 949, 0x0a},
> + { 999, 0x1a}, {1049, 0x2a}, {1099, 0x3a}, {1149, 0x0b},
> + {1199, 0x1b}, {1249, 0x2b}, {1299, 0x3b}, {1349, 0x0c},
> + {1399, 0x1c}, {1449, 0x2c}, {1500, 0x3c}
> +};
> +
> +static const char * const rk3399_mipidphy_clks[] = {
> + "dphy-ref",
> + "dphy-cfg",
> + "grf",
> +};
> +
> +enum dphy_reg_id {
> + GRF_DPHY_RX0_TURNDISABLE = 0,
> + GRF_DPHY_RX0_FORCERXMODE,
> + GRF_DPHY_RX0_FORCETXSTOPMODE,
> + GRF_DPHY_RX0_ENABLE,
> + GRF_DPHY_RX0_TESTCLR,
> + GRF_DPHY_RX0_TESTCLK,
> + GRF_DPHY_RX0_TESTEN,
> + GRF_DPHY_RX0_TESTDIN,
> + GRF_DPHY_RX0_TURNREQUEST,
> + GRF_DPHY_RX0_TESTDOUT,
> + GRF_DPHY_TX0_TURNDISABLE,
> + GRF_DPHY_TX0_FORCERXMODE,
> + GRF_DPHY_TX0_FORCETXSTOPMODE,
> + GRF_DPHY_TX0_TURNREQUEST,
> + GRF_DPHY_TX1RX1_TURNDISABLE,
> + GRF_DPHY_TX1RX1_FORCERXMODE,
> + GRF_DPHY_TX1RX1_FORCETXSTOPMODE,
> + GRF_DPHY_TX1RX1_ENABLE,
> + GRF_DPHY_TX1RX1_MASTERSLAVEZ,
> + GRF_DPHY_TX1RX1_BASEDIR,
> + GRF_DPHY_TX1RX1_ENABLECLK,
> + GRF_DPHY_TX1RX1_TURNREQUEST,
> + GRF_DPHY_RX1_SRC_SEL,
> + /* rk3288 only */
> + GRF_CON_DISABLE_ISP,
> + GRF_CON_ISP_DPHY_SEL,
> + GRF_DSI_CSI_TESTBUS_SEL,
> + GRF_DVP_V18SEL,
> + /* below is for rk3399 only */
> + GRF_DPHY_RX0_CLK_INV_SEL,
> + GRF_DPHY_RX1_CLK_INV_SEL,
> +};
> +
> +struct dphy_reg {
> + u32 offset;
> + u32 mask;
> + u32 shift;
> +};
> +
> +#define PHY_REG(_offset, _width, _shift) \
> + { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
> +
> +static const struct dphy_reg rk3399_grf_dphy_regs[] = {
> + [GRF_DPHY_RX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON9, 4, 0),
> + [GRF_DPHY_RX0_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 10),
> + [GRF_DPHY_RX1_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 11),
> + [GRF_DPHY_RX0_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 0),
> + [GRF_DPHY_RX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 4),
> + [GRF_DPHY_RX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 8),
> + [GRF_DPHY_RX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 12),
> + [GRF_DPHY_TX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 0),
> + [GRF_DPHY_TX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 4),
> + [GRF_DPHY_TX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 8),
> + [GRF_DPHY_TX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 12),
> + [GRF_DPHY_TX1RX1_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 0),
> + [GRF_DPHY_TX1RX1_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 4),
> + [GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
> + [GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
> + [GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
> + [GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
> + [GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
> + [GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
> + [GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
> + [GRF_DPHY_RX0_TESTDIN] = PHY_REG(RK3399_GRF_SOC_CON25, 8, 0),
> + [GRF_DPHY_RX0_TESTEN] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 8),
> + [GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
> + [GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
> + [GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
> +};
> +
> +struct dphy_drv_data {
> + const char * const *clks;
> + int num_clks;
> + const struct hsfreq_range *hsfreq_ranges;
> + int num_hsfreq_ranges;
> + const struct dphy_reg *regs;
> +};
> +
> +struct rockchip_dphy {
> + struct device *dev;
> + struct regmap *grf;
> + const struct dphy_reg *grf_regs;
> + struct clk_bulk_data clks[MAX_DPHY_CLK];
> +
> + const struct dphy_drv_data *drv_data;
> + struct phy_configure_opts_mipi_dphy config;
> +};
> +
> +static inline void write_grf_reg(struct rockchip_dphy *priv,
> + int index, u8 value)
> +{
> + const struct dphy_reg *reg = &priv->grf_regs[index];
> + unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
> +
> + WARN_ON(!reg->offset);
> + regmap_write(priv->grf, reg->offset, val);
> +}
> +
> +static void mipidphy0_wr_reg(struct rockchip_dphy *priv,
> + u8 test_code, u8 test_data)
> +{
> + /*
> + * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
> + * is latched internally as the current test code. Test data is
> + * programmed internally by rising edge on TESTCLK.
> + */
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTDIN, test_code);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTEN, 1);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 0);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTEN, 0);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTDIN, test_data);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
> +}
> +
> +/* should be move to power_on */
> +static int mipidphy_rx_stream_on(struct rockchip_dphy *priv)
> +{
> + const struct dphy_drv_data *drv_data = priv->drv_data;
> + const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges;
> + struct phy_configure_opts_mipi_dphy *config = &priv->config;
> + unsigned int i, hsfreq = 0, data_rate_mbps = config->hs_clk_rate;
> + int num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
> +
> + do_div(data_rate_mbps, 1000 * 1000);
> +
> + dev_dbg(priv->dev, "%s: lanes %d - data_rate_mbps %u\n",
> + __func__, config->lanes, data_rate_mbps);
> +
> + for (i = 0; i < num_hsfreq_ranges; i++) {
> + if (hsfreq_ranges[i].range_h >= data_rate_mbps) {
> + hsfreq = hsfreq_ranges[i].cfg_bit;
> + break;
> + }
> + }
> +
> + write_grf_reg(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
> + write_grf_reg(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
> +
> + /* Disable lan turn around, which is ignored in receive mode */
> + write_grf_reg(priv, GRF_DPHY_RX0_TURNREQUEST, 0);
> + write_grf_reg(priv, GRF_DPHY_RX0_TURNDISABLE, 0xf);
> +
> + write_grf_reg(priv, GRF_DPHY_RX0_ENABLE, GENMASK(config->lanes - 1, 0));
> +
> + /* dphy start */
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLR, 1);
> + usleep_range(100, 150);
> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLR, 0);
> + usleep_range(100, 150);
> +
> + /* set clock lane */
> + /* HS hsfreq_range & lane 0 settle bypass */
> + mipidphy0_wr_reg(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
> + /* HS RX Control of lane0 */
> + mipidphy0_wr_reg(priv, LANE0_HS_RX_CONTROL, hsfreq << 1);
> + /* HS RX Control of lane1 */
> + mipidphy0_wr_reg(priv, LANE1_HS_RX_CONTROL, 0);
> + /* HS RX Control of lane2 */
> + mipidphy0_wr_reg(priv, LANE2_HS_RX_CONTROL, 0);
> + /* HS RX Control of lane3 */
> + mipidphy0_wr_reg(priv, LANE3_HS_RX_CONTROL, 0);
> + /* HS RX Data Lanes Settle State Time Control */
> + mipidphy0_wr_reg(priv, HS_RX_DATA_LANES_THS_SETTLE_CONTROL,
> + THS_SETTLE_COUNTER_THRESHOLD);
> +
> + /* Normal operation */
> + mipidphy0_wr_reg(priv, 0x0, 0);
> +
> + return 0;
> +}
> +
> +static int rockchip_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> +{
> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
> + int ret;
> +
> + /* pass with phy_mipi_dphy_get_default_config (with pixel rate?) */
> + ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
> + if (ret)
> + return ret;
> +
> + memcpy(&priv->config, opts, sizeof(priv->config));
You could to:
priv->config = *opts;
Up to you. Some people like memcpy(). :-)
> +
> + return 0;
> +}
> +
> +static int rockchip_dphy_power_on(struct phy *phy)
> +{
> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = clk_bulk_enable(priv->drv_data->num_clks, priv->clks);
> + if (ret)
> + return ret;
> +
> + return mipidphy_rx_stream_on(priv);
> +}
> +
> +static int rockchip_dphy_power_off(struct phy *phy)
> +{
> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
> +
> + clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
> + return 0;
> +}
> +
> +static int rockchip_dphy_init(struct phy *phy)
> +{
> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = clk_bulk_prepare(priv->drv_data->num_clks, priv->clks);
return ...;
> + if (ret)
> + return ret;
> + return 0;
> +}
> +
> +static int rockchip_dphy_exit(struct phy *phy)
> +{
> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
> +
> + clk_bulk_unprepare(priv->drv_data->num_clks, priv->clks);
> + return 0;
> +}
> +
> +static const struct phy_ops rockchip_dphy_ops = {
> + .power_on = rockchip_dphy_power_on,
> + .power_off = rockchip_dphy_power_off,
> + .init = rockchip_dphy_init,
> + .exit = rockchip_dphy_exit,
> + .configure = rockchip_dphy_configure,
> + .owner = THIS_MODULE,
> +};
> +
> +static const struct dphy_drv_data rk3399_mipidphy_drv_data = {
> + .clks = rk3399_mipidphy_clks,
> + .num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
> + .hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
> + .num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
> + .regs = rk3399_grf_dphy_regs,
Do you expect to support more of the similar PHY(s) --- are there such? If
not, you could put these in the code that uses them.
> +};
> +
> +static const struct of_device_id rockchip_dphy_dt_ids[] = {
> + {
> + .compatible = "rockchip,rk3399-mipi-dphy",
> + .data = &rk3399_mipidphy_drv_data,
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, rockchip_dphy_dt_ids);
> +
> +static int rockchip_dphy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + const struct dphy_drv_data *drv_data;
> + struct phy_provider *phy_provider;
> + const struct of_device_id *of_id;
> + struct rockchip_dphy *priv;
> + struct regmap *grf;
> + struct phy *phy;
> + unsigned int i;
> + int ret;
> +
> + if (!dev->parent || !dev->parent->of_node)
> + return -ENODEV;
> +
> + if (platform_get_resource(pdev, IORESOURCE_MEM, 0)) {
> + dev_err(&pdev->dev, "Rockchip DPHY driver only suports rx\n");
> + return -EINVAL;
> + }
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> + priv->dev = dev;
> +
> + grf = syscon_node_to_regmap(dev->parent->of_node);
> + if (IS_ERR(grf)) {
> + grf = syscon_regmap_lookup_by_phandle(dev->of_node,
> + "rockchip,grf");
> + if (IS_ERR(grf)) {
> + dev_err(dev, "Can't find GRF syscon\n");
> + return -ENODEV;
> + }
> + }
> + priv->grf = grf;
> +
> + of_id = of_match_device(rockchip_dphy_dt_ids, dev);
> + if (!of_id)
> + return -EINVAL;
> +
> + drv_data = of_id->data;
> + priv->grf_regs = drv_data->regs;
> + priv->drv_data = drv_data;
> + for (i = 0; i < drv_data->num_clks; i++)
> + priv->clks[i].id = drv_data->clks[i];
> + ret = devm_clk_bulk_get(&pdev->dev, drv_data->num_clks, priv->clks);
> + if (ret)
> + return ret;
> +
> + phy = devm_phy_create(dev, np, &rockchip_dphy_ops);
> + if (IS_ERR(phy)) {
> + dev_err(dev, "failed to create phy\n");
> + return PTR_ERR(phy);
> + }
> + phy_set_drvdata(phy, priv);
> +
> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> + return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static struct platform_driver rockchip_dphy_driver = {
> + .probe = rockchip_dphy_probe,
> + .driver = {
> + .name = "rockchip-mipi-dphy",
> + .of_match_table = rockchip_dphy_dt_ids,
> + },
> +};
> +module_platform_driver(rockchip_dphy_driver);
> +
> +MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
> +MODULE_DESCRIPTION("Rockchip MIPI Synopsys DPHY driver");
> +MODULE_LICENSE("Dual MIT/GPL");
--
Kind regards,
Sakari Ailus
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 02/14] media: doc: add document for rkisp1 meta buffer format
From: Sakari Ailus @ 2019-08-07 13:09 UTC (permalink / raw)
To: Helen Koike
Cc: devicetree, eddie.cai.linux, kernel, heiko, Jacob Chen,
jacob2.chen, jeffy.chen, zyc, linux-kernel, tfiga, linux-rockchip,
hans.verkuil, laurent.pinchart, zhengsq, mchehab, ezequiel,
linux-arm-kernel, linux-media
In-Reply-To: <20190730184256.30338-3-helen.koike@collabora.com>
Hi Helen,
On Tue, Jul 30, 2019 at 03:42:44PM -0300, Helen Koike wrote:
> From: Jacob Chen <jacob2.chen@rock-chips.com>
>
> This commit add document for rkisp1 meta buffer format
>
> Signed-off-by: Jacob Chen <jacob-chen@rock-chips.com>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> [update for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.com>
>
> ---
>
> Changes in v8:
> - Add SPDX in the header
> - Remove emacs configs
> - Fix doc style
>
> Changes in v7:
> - s/correspond/corresponding
> - s/use/uses
> - s/docuemnt/document
>
> Documentation/media/uapi/v4l/meta-formats.rst | 2 ++
> .../uapi/v4l/pixfmt-meta-rkisp1-params.rst | 23 +++++++++++++++++++
> .../uapi/v4l/pixfmt-meta-rkisp1-stat.rst | 22 ++++++++++++++++++
> 3 files changed, 47 insertions(+)
> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst
> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst
>
> diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
> index b10ca9ee3968..5de621fea3cc 100644
> --- a/Documentation/media/uapi/v4l/meta-formats.rst
> +++ b/Documentation/media/uapi/v4l/meta-formats.rst
> @@ -24,3 +24,5 @@ These formats are used for the :ref:`metadata` interface only.
> pixfmt-meta-uvc
> pixfmt-meta-vsp1-hgo
> pixfmt-meta-vsp1-hgt
> + pixfmt-meta-rkisp1-params
> + pixfmt-meta-rkisp1-stat
> diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst b/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst
> new file mode 100644
> index 000000000000..103b5cb79b7c
> --- /dev/null
> +++ b/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst
> @@ -0,0 +1,23 @@
> +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +.. _v4l2-meta-fmt-rkisp1-params:
> +
> +============================
> +V4L2_META_FMT_RK_ISP1_PARAMS
> +============================
> +
> +Rockchip ISP1 Parameters Data
> +
> +Description
> +===========
> +
> +This format describes input parameters for the Rockchip ISP1.
> +
> +It uses c-struct :c:type:`rkisp1_isp_params_cfg`, which is defined in
> +the ``linux/rkisp1-config.h`` header file.
Do you have an insight on in which order the device executes the processing
steps for the image data? The pipeline may not be entirely linear either
(statistics, for instance). This should be included in the documentation.
> +
> +The parameters consist of multiple modules.
> +The module won't be updated if the corresponding bit was not set in module_*_update.
> +
> +.. kernel-doc:: include/uapi/linux/rkisp1-config.h
> + :functions: rkisp1_isp_params_cfg
> diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst b/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst
> new file mode 100644
> index 000000000000..4ad303f96421
> --- /dev/null
> +++ b/Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst
> @@ -0,0 +1,22 @@
> +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +.. _v4l2-meta-fmt-rkisp1-stat:
> +
> +=============================
> +V4L2_META_FMT_RK_ISP1_STAT_3A
> +=============================
> +
> +
> +Rockchip ISP1 Statistics Data
> +
> +Description
> +===========
> +
> +This format describes image color statistics information generated by the Rockchip
> +ISP1.
> +
> +It uses c-struct :c:type:`rkisp1_stat_buffer`, which is defined in
> +the ``linux/rkisp1-config.h`` header file.
> +
> +.. kernel-doc:: include/uapi/linux/rkisp1-config.h
> + :functions: rkisp1_stat_buffer
--
Kind regards,
Sakari Ailus
sakari.ailus@linux.intel.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] mfd: db8500-prcmu: Mark expected switch fall-throughs
From: Linus Walleij @ 2019-08-07 13:12 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Stephen Rothwell, Lee Jones, linux-kernel@vger.kernel.org,
Linux ARM, Kees Cook
In-Reply-To: <20190728235614.GA23618@embeddedor>
On Mon, Jul 29, 2019 at 1:56 AM Gustavo A. R. Silva
<gustavo@embeddedor.com> wrote:
> Mark switch cases where we are expecting to fall through.
>
> This patch fixes the following warnings:
>
> drivers/mfd/db8500-prcmu.c: In function 'dsiclk_rate':
> drivers/mfd/db8500-prcmu.c:1592:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
> div *= 2;
> ~~~~^~~~
> drivers/mfd/db8500-prcmu.c:1593:2: note: here
> case PRCM_DSI_PLLOUT_SEL_PHI_2:
> ^~~~
> drivers/mfd/db8500-prcmu.c:1594:7: warning: this statement may fall through [-Wimplicit-fallthrough=]
> div *= 2;
> ~~~~^~~~
> drivers/mfd/db8500-prcmu.c:1595:2: note: here
> case PRCM_DSI_PLLOUT_SEL_PHI:
> ^~~~
>
> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/9] KVM: arm64: Document PV-time interface
From: Steven Price @ 2019-08-07 13:21 UTC (permalink / raw)
To: Christophe de Dinechin
Cc: Radim Krčmář, kvm, Suzuki K Pouloze,
Catalin Marinas, linux-doc, Russell King, linux-kernel,
James Morse, Julien Thierry, Marc Zyngier, Paolo Bonzini,
Will Deacon, kvmarm, linux-arm-kernel
In-Reply-To: <m1mugnmv0x.fsf@dinechin.org>
On 05/08/2019 17:40, Christophe de Dinechin wrote:
>
> Steven Price writes:
>
>> Introduce a paravirtualization interface for KVM/arm64 based on the
>> "Arm Paravirtualized Time for Arm-Base Systems" specification DEN 0057A.
>>
>> This only adds the details about "Stolen Time" as the details of "Live
>> Physical Time" have not been fully agreed.
>>
> [...]
>
>> +
>> +Stolen Time
>> +-----------
>> +
>> +The structure pointed to by the PV_TIME_ST hypercall is as follows:
>> +
>> + Field | Byte Length | Byte Offset | Description
>> + ----------- | ----------- | ----------- | --------------------------
>> + Revision | 4 | 0 | Must be 0 for version 0.1
>> + Attributes | 4 | 4 | Must be 0
>> + Stolen time | 8 | 8 | Stolen time in unsigned
>> + | | | nanoseconds indicating how
>> + | | | much time this VCPU thread
>> + | | | was involuntarily not
>> + | | | running on a physical CPU.
>
> I know very little about the topic, but I don't understand how the spec
> as proposed allows an accurate reading of the relation between physical
> time and stolen time simultaneously. In other words, could you draw
> Figure 1 of the spec from within the guest? Or is it a non-objective?
Figure 1 is mostly attempting to explain Live Physical Time (LPT), which
is not part of this patch series. But it does touch on stolen time by
the difference between "live physical time" and "virtual time".
I'm not sure what you mean by "from within the guest". From the
perspective of the guest the parts of the diagram where the guest isn't
running don't exist (therefore there are discontinuities in the
"physical time" and "live physical time" lines).
This patch series doesn't attempt to provide the guest with a view of
"physical time" (or LPT) - but it might be able to observe that by
consulting something external (e.g. an NTP server, or an emulated RTC
which reports wall-clock time).
What it does provide is a mechanism for obtaining the difference (as
reported by the host) between "live physical time" and "virtual time" -
this is reported in nanoseconds in the above structure.
> For example, if you read the stolen time before you read CNTVCT_EL0,
> isn't it possible for a lengthy event like a migration to occur between
> the two reads, causing the stolen time to be obsolete and off by seconds?
"Lengthy events" like migration are represented by the "paused" state in
the diagram - i.e. it's the difference between "physical time" and "live
physical time". So stolen time doesn't attempt to represent that.
And yes, there is a race between reading CNTVCT_EL0 and reading stolen
time - but in practice this doesn't really matter. The usual pseudo-code
way of using stolen time is:
* scheduler captures stolen time from structure and CNTVCT_EL0:
before_timer = CNTVCT_EL0
before_stolen = stolen
* schedule in process
* process is pre-empted (or blocked in some way)
* scheduler captures stolen time from structure and CNTVCT_EL0:
after_timer = CNTVCT_EL0
after_stolen = stolen
time = to_nsecs(after_timer - before_timer) -
(after_stolen - before_stolen)
The scheduler can then charge the process for "time" nanoseconds of
time. This ensures that a process isn't unfairly penalised if the host
doesn't schedule the VCPU while it is supposed to be running.
The race is very small in comparison to the time the process is running,
and in the worst case just means the process is charged slightly more
(or less) than it should be.
I guess if you're really worried about it, you could do a dance like:
do {
before = stolen
timer = CNTVCT_EL0
after = stolen
} while (before != after);
But I don't see the need to have such an accurate view of elapsed time
that the VCPU was scheduled. And of course at the moment (without this
series) the guest has no idea about time stolen by the host.
Steve
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC,v3 7/9] media: platform: Add Mediatek ISP P1 device driver
From: Tomasz Figa @ 2019-08-07 13:25 UTC (permalink / raw)
To: Jungo Lin
Cc: devicetree, Sean Cheng (鄭昇弘),
Mauro Carvalho Chehab, Rynn Wu (吳育恩),
srv_heupstream, Rob Herring, Ryan Yu (余孟修),
Frankie Chiu (邱文凱), Hans Verkuil,
Matthias Brugger, Sj Huang,
moderated list:ARM/Mediatek SoC support, Laurent Pinchart,
ddavenport, Frederic Chen (陳俊元),
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Linux Media Mailing List
In-Reply-To: <1565143899.9157.19.camel@mtksdccf07>
On Wed, Aug 7, 2019 at 11:11 AM Jungo Lin <jungo.lin@mediatek.com> wrote:
>
> Hi, Tomasz:
>
> On Tue, 2019-08-06 at 18:47 +0900, Tomasz Figa wrote:
> > Hi Jungo,
> >
> > On Fri, Jul 26, 2019 at 4:24 PM Jungo Lin <jungo.lin@mediatek.com> wrote:
> > >
> > > Hi, Tomasz:
> > >
> > > On Thu, 2019-07-25 at 18:23 +0900, Tomasz Figa wrote:
> > > > .Hi Jungo,
> > > >
> > > > On Sat, Jul 20, 2019 at 6:58 PM Jungo Lin <jungo.lin@mediatek.com> wrote:
> > > > >
> > > > > Hi, Tomasz:
> > > > >
> > > > > On Wed, 2019-07-10 at 18:56 +0900, Tomasz Figa wrote:
> > > > > > Hi Jungo,
> > > > > >
> > > > > > On Tue, Jun 11, 2019 at 11:53:42AM +0800, Jungo Lin wrote:
> > [snip]
>
> I just keep some questions to be clarified.
> [snip]
>
> > > > > > > + isp_dev->meta0_vb2_index = meta0_vb2_index;
> > > > > > > + isp_dev->meta1_vb2_index = meta1_vb2_index;
> > > > > > > + } else {
> > > > > > > + if (irq_status & SOF_INT_ST) {
> > > > > > > + isp_dev->current_frame = hw_frame_num;
> > > > > > > + isp_dev->meta0_vb2_index = meta0_vb2_index;
> > > > > > > + isp_dev->meta1_vb2_index = meta1_vb2_index;
> > > > > > > + }
> > > > > > > + irq_handle_notify_event(isp_dev, irq_status, dma_status, 1);
> > > > > > > + }
> > > > > >
> > > > > > The if and else blocks do almost the same things just in different order. Is
> > > > > > it really expected?
> > > > > >
> > > > >
> > > > > If we receive HW_PASS1_DON_ST & SOF_INT_ST IRQ events at the same time,
> > > > > the correct sequence should be handle HW_PASS1_DON_ST firstly to check
> > > > > any de-queued frame and update the next frame setting later.
> > > > > Normally, this is a corner case or system performance issue.
> > > >
> > > > So it sounds like HW_PASS1_DON_ST means that all data from current
> > > > frame has been written, right? If I understand your explanation above
> > > > correctly, that would mean following handling of each interrupt:
> > > >
> > > > HW_PASS1_DON_ST:
> > > > - CQ executes with next CQ buffer to prepare for next frame. <- how
> > > > is this handled? does the CQ hardware automatically receive this event
> > > > from the ISP hadware?
> > > > - return VB2 buffers,
> > > > - complete requests.
> > > >
> > > > SOF_INT_ST:
> > > > - send VSYNC event to userspace,
> > > > - program next CQ buffer to CQ,
> > > >
> > > > SW_PASS1_DON_ST:
> > > > - reclaim CQ buffer and enqueue next frame to composing if available
> > > >
> > >
> > > Sorry for our implementation of HW_PASS1_DON_ST.
> > > It is confusing.
> > > Below is the revised version based on your conclusion.
> > > So in our new implemmenation, we just handle SOF_INT_ST &
> > > SW_PASS1_DON_ST events. We just add one warning message for
> > > HW_PASS1_DON_ST
> > >
> > > HW_PASS1_DON_ST:
> > > - CQ executes with next CQ buffer to prepare for next frame.
> > >
> > > SOF_INT_ST:
> > > - send VSYNC event to userspace,
> > > - program next CQ buffer to CQ,
> > >
> > > SW_PASS1_DON_ST:
> > > - reclaim CQ buffer and enqueue next frame to composing if available
> > > - return VB2 buffers,
> > > - complete requests.
> > >
> > > For CQ HW operations, it is listed below:
> > >
> > > a. The CQ buffer has two kinds of information
> > > - Which ISP registers needs to be updated.
> > > - Where the corresponding ISP register data to be read.
> > > b. The CQ buffer loading procedure is triggered by HW_PASS1_DONT_ST IRQ
> > > event periodically.
> > > - Normally, if the ISP HW receives the completed frame and it will
> > > trigger W_PASS1_DONT_ST IRQ and perform CQ buffer loading immediately.
> > > - So the CQ buffer loading is performed by ISP HW automatically.
> > > c. The ISP HW will read CQ base address register(REG_CQ_THR0_BASEADDR)
> > > to decide which CQ buffer is loaded.
> > > - So we configure the next CQ base address in SOF.
> > > d. For CQ buffer loading, CQ will read the ISP registers from CQ buffer
> > > and update the ISP register values into HW.
> > > - SCP composer will compose one dummy CQ buffer and assign it to
> > > REG_CQ_THR0_BASEADDR of each CQ buffer.
> > > - Dummy CQ buffer has no updated ISP registers comparing with other
> > > CQ buffers.
> > > - With this design, if there is no updated new CQ buffer by driver
> > > which may be caused no en-queue frames from user space. The CQ HW will
> > > load dummy CQ buffer and do nothing.
> >
> > Does the set of registers programmed by CQ include destination buffer
> > addresses to? If yes, we would end up overwriting previous frames if
> > no new buffers are provided.
> >
>
> Yes, the buffer addresses are changed per frame request. We need to
> compose CQ to include these DMA destination addresses. For your concern,
> we have DMA flow buffer control (FBC) in HW. If there is no FBC counter
> increased due to no buffer for each DMA, the ISP HW doesn't output the
> data to the corresponding DMA address.
>
> Below is the simple descriptor of CQ buffer.
> a. ISP registers in tuning buffer, including 3A registers.
> b. All capture buffers informations.
> - DMA buffer destination address
> - FBC counter
> c. Some specif ISP registers for meta DMAs, such as LCE or LMVO.
> d. frame sequence number register
>
Okay, with the FBC counter it sounds fine. Thanks for clarifying.
> > > f. The CQ buffer loading is guaranteed by HW to finish before the next
> > > SOF.
> > >
> >
> > Okay, thanks a lot for the explanation. This is much more clear now.
> >
> > [snip]
> > > > > > > +static const struct dev_pm_ops mtk_isp_pm_ops = {
> > > > > > > + SET_SYSTEM_SLEEP_PM_OPS(mtk_isp_suspend, mtk_isp_resume)
> > > > > > > + SET_RUNTIME_PM_OPS(mtk_isp_suspend, mtk_isp_resume, NULL)
> > > > > >
> > > > > > For V4L2 drivers system and runtime PM ops would normally be completely
> > > > > > different. Runtime PM ops would be called when the hardware is idle already
> > > > > > or is about to become active. System PM ops would be called at system power
> > > > > > state change and the hardware might be both idle or active. Please also see
> > > > > > my comments to mtk_isp_suspend() and mtk_isp_resume() above.
> > > > > >
> > > > >
> > > > > Here is the new implementation. It should be clear to show the
> > > > > difference between system and runtime PM ops.
> > > > >
> > > > > static const struct dev_pm_ops mtk_isp_pm_ops = {
> > > > > SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > > > > pm_runtime_force_resume)
> > > > > SET_RUNTIME_PM_OPS(mtk_isp_runtime_suspend, mtk_isp_runtime_resume,
> > > > > NULL)
> > > > > };
> > > >
> > > > That's still not correct. In runtime suspend/resume ops we already are
> > > > not streaming anymore, because we call pm_runtime_get/put_*() when
> > > > starting and stopping streaming. In system suspend/resume ops we might
> > > > be streaming and that's when we need to stop the hardware and wait for
> > > > it to finish. Please implement these ops separately.
> > > >
> > > > Best regards,
> > > > Tomasz
> > >
> > >
> > > Ok, got your point.
> > > Below is the new implementation for your review.
> > >
> > > static int mtk_isp_pm_suspend(struct device *dev)
> > > {
> > > struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> > > u32 val;
> > > int ret;
> > >
> > > dev_dbg(dev, "- %s\n", __func__);
> > >
> > > /* Check ISP is streaming or not */
> > > if (!p1_dev->cam_dev.streaming)
> > > goto done;
> >
> > We would normally check here for pm_runtime_suspended(). Although they
> > both should be equivalent. Still, there is no need to call
> > pm_runtime_force_suspend() if the latter is true, so we could just
> > return 0 instantly.
> >
>
> Ok, here is the fixed version.
>
> static int mtk_isp_pm_suspend(struct device *dev)
> {
> struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> u32 val;
> int ret;
>
> dev_dbg(dev, "- %s\n", __func__);
>
> if (pm_runtime_suspended(dev))
> return 0;
>
> /* Disable ISP's view finder and wait for TG idle */
> dev_dbg(dev, "cam suspend, disable VF\n");
> val = readl(p1_dev->regs + REG_TG_VF_CON);
> writel(val & (~TG_VF_CON_VFDATA_EN), p1_dev->regs + REG_TG_VF_CON);
> ret = readl_poll_timeout_atomic(p1_dev->regs + REG_TG_INTER_ST, val,
> (val & TG_CS_MASK) == TG_IDLE_ST,
> USEC_PER_MSEC, MTK_ISP_STOP_HW_TIMEOUT);
> if (ret)
> dev_warn(dev, "can't stop HW:%d:0x%x\n", ret, val);
What happens in this case? Is it safe to continue?
>
> /* Disable CMOS */
> val = readl(p1_dev->regs + REG_TG_SEN_MODE);
> writel(val & (~TG_SEN_MODE_CMOS_EN), p1_dev->regs + REG_TG_SEN_MODE);
>
> /* Force ISP HW to idle */
> ret = pm_runtime_force_suspend(dev);
> if (ret)
> return ret;
We should probably reenable the hardware if the above failed, so that
we hopefully end up in the same state as before the suspend.
>
> return 0;
> }
> [snip]
>
> > > static int mtk_isp_pm_resume(struct device *dev)
> > > {
> > > struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> > > u32 val;
> > > int ret;
> > >
> > > dev_dbg(dev, "- %s\n", __func__);
> > >
> > > /* Force ISP HW to resume if needed */
> > > ret = pm_runtime_force_resume(dev);
> > > if (ret)
> > > return ret;
> >
> > We should do this conditionally based on what pm_runtime_suspended()
> > returns. If it's non-zero then we can just return 0 instantly.
> >
>
> Ok, here is the fixed version.
>
> static int mtk_isp_pm_resume(struct device *dev)
> {
> struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> u32 val;
> int ret;
>
> dev_dbg(dev, "- %s\n", __func__);
>
> if (pm_runtime_suspended(dev))
> return 0;
>
> /* Force ISP HW to resume */
> ret = pm_runtime_force_resume(dev);
> if (ret)
> return ret;
>
> /* Enable CMOS */
> dev_dbg(dev, "cam resume, enable CMOS/VF\n");
> val = readl(p1_dev->regs + REG_TG_SEN_MODE);
> writel(val | TG_SEN_MODE_CMOS_EN, p1_dev->regs + REG_TG_SEN_MODE);
>
> /* Enable VF */
> val = readl(p1_dev->regs + REG_TG_VF_CON);
> writel(val | TG_VF_CON_VFDATA_EN, p1_dev->regs + REG_TG_VF_CON);
>
> return 0;
> }
>
> [snip]
>
> > > static int mtk_isp_runtime_suspend(struct device *dev)
> > > {
> > > struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> > >
> > > dev_dbg(dev, "- %s\n", __func__);
> > >
> > > if (pm_runtime_suspended(dev))
> > > return 0;
> >
> > Sorry, I guess I wasn't clear in my reply. It's not possible to get
> > this callback called if the device is already runtime suspended.
> >
>
> Ok, got it. Need to remove pm_runtime_suspended(dev) checking and move
> it into mtk_isp_pm_* functions. If I still don't get your point, could
> you kindly provide one sample driver for reference?
The above implementation is okay, thanks. :)
> Based on current
> implementation, it is similar to below drivers.
> https://elixir.bootlin.com/linux/latest/source/drivers/media/platform/mtk-mdp/mtk_mdp_core.c#L255
> https://elixir.bootlin.com/linux/latest/source/drivers/media/platform/exynos4-is/fimc-is-i2c.c#L113
>
The first one is an m2m device so it has slightly different rules -
the runtime PM is allowed to suspend between frames if the idle time
is long enough. The second one is a dummy driver for some fake i2c
bus, so it doesn't really have any meaningful implementation.
I think you could take a look at
https://elixir.bootlin.com/linux/v5.3-rc3/source/drivers/media/platform/exynos4-is/fimc-lite.c#L1550
, which is an online capture device too.
>
> static int mtk_isp_runtime_suspend(struct device *dev)
> {
> struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
>
> dev_dbg(dev, "%s:disable clock\n", __func__);
> clk_bulk_disable_unprepare(p1_dev->num_clks, p1_dev->clks);
>
> return 0;
> }
>
> [snip]
>
> > > static int mtk_isp_runtime_resume(struct device *dev)
> > > {
> > > struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> > > int ret;
> > >
> > > dev_dbg(dev, "- %s\n", __func__);
> > >
> > > if (pm_runtime_suspended(dev))
> > > return 0;
> >
> > In this case the above call would always return non-zero, so the
> > behavior wouldn't be very good.
> >
>
> Same as above.
>
> static int mtk_isp_runtime_resume(struct device *dev)
> {
> struct mtk_isp_p1_device *p1_dev = dev_get_drvdata(dev);
> int ret;
>
> dev_dbg(dev, "%s:enable clock\n", __func__);
> ret = clk_bulk_prepare_enable(p1_dev->num_clks, p1_dev->clks);
> if (ret) {
> dev_err(dev, "failed to enable clock:%d\n", ret);
> return ret;
> }
>
> return 0;
> }
Makes sense, thanks!
Best regards,
Tomasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V4 06/11] arm64: mm: Introduce VA_BITS_ACTUAL
From: Steve Capper @ 2019-08-07 13:27 UTC (permalink / raw)
To: Catalin Marinas
Cc: crecklin@redhat.com, ard.biesheuvel@linaro.org, maz@kernel.org,
bhsharma@redhat.com, nd, will@kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190806144833.GE30716@arrakis.emea.arm.com>
On Tue, Aug 06, 2019 at 03:48:33PM +0100, Catalin Marinas wrote:
> On Tue, Aug 06, 2019 at 11:32:04AM +0000, Steve Capper wrote:
> > On Mon, Aug 05, 2019 at 06:26:43PM +0100, Catalin Marinas wrote:
> > > On Mon, Jul 29, 2019 at 05:21:12PM +0100, Steve Capper wrote:
> > > > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> > > > index a8a91a573bff..93341f4fe840 100644
> > > > --- a/arch/arm64/include/asm/memory.h
> > > > +++ b/arch/arm64/include/asm/memory.h
> > > > @@ -37,8 +37,6 @@
> > > > * VA_START - the first kernel virtual address.
> > > > */
> > > > #define VA_BITS (CONFIG_ARM64_VA_BITS)
> > > > -#define VA_START (UL(0xffffffffffffffff) - \
> > > > - (UL(1) << (VA_BITS - 1)) + 1)
> > > > #define PAGE_OFFSET (UL(0xffffffffffffffff) - \
> > > > (UL(1) << VA_BITS) + 1)
> > > > #define KIMAGE_VADDR (MODULES_END)
> > > > @@ -166,10 +164,14 @@
> > > > #endif
> > > >
> > > > #ifndef __ASSEMBLY__
> > > > +extern u64 vabits_actual;
> > > > +#define VA_BITS_ACTUAL ({vabits_actual;})
> > >
> > > Why not use the variable vabits_actual directly instead of defining a
> > > macro?
> >
> > I thought that it would look better to have an uppercase name for the
> > actual VA bits to match the existing code style for VA_BITS.
> >
> > I can just rename vabits_actual => VA_BITS_ACTUAL and get rid of the
> > macro?
>
> By tradition we use uppercase for macros and lowercase for variables. So
> I'd definitely keep the variable lowercase.
>
> If you prefer to keep the macro as well, fine by me, I don't think we
> should bikeshed here.
Having thought about it I prefer the lower case recommendation as it's
a variable. So have made this change. :-)
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] kernfs: fix memleak in kernel_ops_readdir()
From: Tony Lindgren @ 2019-08-07 13:29 UTC (permalink / raw)
To: Tejun Heo
Cc: Andrea Arcangeli, Greg Kroah-Hartman, Russell King, linux-kernel,
~, linux-omap, linux-arm-kernel
In-Reply-To: <20190805173404.GF136335@devbig004.ftw2.facebook.com>
Hi,
* Tejun Heo <tj@kernel.org> [691231 23:00]:
> From: Andrea Arcangeli <aarcange@redhat.com>
>
> If getdents64 is killed or hits on segfault, it'll leave cgroups
> directories in sysfs pinned leaking memory because the kernfs node
> won't be freed on rmdir and the parent neither.
Somehow this causes a regression in Linux next for me where I'm seeing
lots of sysfs entries now missing under /sys/bus/platform/devices.
For example, I now only see one .serial entry show up in sysfs.
Things work again if I revert commit cc798c83898e ("kernfs: fix memleak
inkernel_ops_readdir()"). Any ideas why that would be?
Below is a diff -u of ls /sys/bus/platform/devices for reference
showing the missing entries with cc798c83898e.
Regards,
Tony
8< -----------------------
--- works
+++ fails
@@ -1,227 +1,44 @@
-2c000000.ethernet
40100000.interconnect
-40100000.interconnect:segment@0
-40122000.mcbsp
-4012208c.target-module
-4012408c.target-module
4012608c.target-module
-40128000.target-module
-4012c000.target-module
-4012e000.target-module
-40130000.target-module
-40130000.wdt
-40132000.target-module
40138000.target-module
-40138000.timer
-4013a000.target-module
-4013a000.timer
-4013c000.target-module
-4013c000.timer
4013e000.target-module
-4013e000.timer
-401f1000.target-module
-40304000.ocmcram
-44000000.ocp
-48000000.interconnect
-48000000.interconnect:segment@0
-48000000.interconnect:segment@200000
-48020000.serial
-48020050.target-module
-48032000.target-module
-48032000.timer
-48034000.target-module
-48034000.timer
-48036000.target-module
48036000.timer
-4803e000.target-module
-4803e000.timer
48055000.gpio
-48055000.target-module
-48057000.gpio
-48057000.target-module
-48059000.gpio
48059000.target-module
-4805b000.gpio
-4805b000.target-module
-4805d000.gpio
4805d000.target-module
-48060000.i2c
-48060000.target-module
-4806a000.serial
-4806a050.target-module
-4806c000.serial
-4806c050.target-module
4806e000.serial
4806e050.target-module
-48070000.i2c
48070000.i2c:twl@48:gpadc
-48070000.i2c:twl@48:pwm
-48070000.i2c:twl@48:pwmled
-48070000.i2c:twl@48:regulator-v1v8
-48070000.i2c:twl@48:regulator-v2v1
48070000.i2c:twl@48:regulator-vana
-48070000.i2c:twl@48:regulator-vaux1
-48070000.i2c:twl@48:regulator-vaux2
-48070000.i2c:twl@48:regulator-vaux3
48070000.i2c:twl@48:regulator-vcxio
-48070000.i2c:twl@48:regulator-vdac
-48070000.i2c:twl@48:regulator-vmmc
-48070000.i2c:twl@48:regulator-vpp
-48070000.i2c:twl@48:regulator-vusb
-48070000.i2c:twl@48:regulator-vusim
-48070000.i2c:twl@48:rtc
48070000.i2c:twl@48:usb-comparator
-48070000.target-module
-48072000.i2c
-48072000.target-module
-48076000.target-module
-48078000.target-module
-48086000.target-module
48086000.timer
-48088000.target-module
-48088000.timer
-4809608c.target-module
-48098000.spi
-48098000.target-module
-4809a000.spi
4809a000.target-module
-4809c000.mmc
4809c000.target-module
-480a5000.des
-480ad000.target-module
-480b2000.1w
-480b2000.target-module
-480b4000.target-module
480b8000.spi
-480b8000.target-module
-480ba000.spi
-480ba000.target-module
-480d1000.target-module
480d5000.mmc
-480d5000.target-module
-48240600.local-timer
48242000.l2-cache-controller
-48350000.i2c
-48350000.target-module
-4a000000.interconnect
-4a000000.interconnect:segment@0
-4a000000.interconnect:segment@100000
-4a000000.interconnect:segment@180000
-4a000000.interconnect:segment@200000
-4a000000.interconnect:segment@280000
4a000000.interconnect:segment@300000
4a000000.interconnect:segment@80000
-4a002000.scm
-4a002000.scm_conf
-4a002000.target-module
-4a002260.bandgap
-4a002300.control-phy
-4a00233c.control-phy
-4a004000.cm1
-4a004000.target-module
-4a004300.mpuss_cm
-4a004400.tesla_cm
-4a004500.abe_cm
-4a008000.cm2
-4a008000.target-module
-4a008600.l4_ao_cm
-4a008700.l3_1_cm
-4a008800.l3_2_cm
-4a008900.ducati_cm
-4a008a00.l3_dma_cm
4a008b00.l3_emif_cm
4a008c00.d2d_cm
-4a008d00.l4_cfg_cm
4a008e00.l3_instr_cm
-4a008f00.ivahd_cm
-4a009000.iss_cm
-4a009100.l3_dss_cm
-4a009200.l3_gfx_cm
-4a009300.l3_init_cm
-4a009400.l4_per_cm
-4a056000.dma-controller
4a056000.target-module
-4a058000.hsi
-4a058000.target-module
4a062000.target-module
-4a062000.usbhstll
-4a064000.target-module
4a064000.usbhshost
4a064800.ohci
-4a064c00.ehci
-4a066000.mmu
-4a0ab000.usb_otg_hs
4a0ab400.target-module
-4a0ad000.ocp2scp
-4a0ad000.target-module
4a0ad080.usb2phy
-4a0d9000.smartreflex
-4a0d9038.target-module
4a0db000.smartreflex
-4a0db038.target-module
-4a0dd000.smartreflex
-4a0dd038.target-module
-4a0f4000.mailbox
-4a0f4000.target-module
-4a0f6000.spinlock
-4a0f6000.target-module
4a100000.target-module
4a100040.pinmux
-4a1005a0.omap4_padconf_global
-4a100600.pbias_regulator
-4a10a000.target-module
-4a300000.interconnect
-4a300000.interconnect:segment@0
-4a300000.interconnect:segment@10000
4a300000.interconnect:segment@20000
-4a306000.prm
-4a306000.target-module
-4a307bd0.regulator-abb-mpu
4a30a000.scrm
-4a30a000.target-module
-4a30c000.target-module
4a30c000.target-module:scm@c000
-4a310000.gpio
-4a310000.target-module
4a314000.target-module
-4a314000.wdt
-4a31c000.keypad
-4a31c000.target-module
-4a31e000.target-module
-4a31e040.pinmux
4b100000.sham
-4b501000.aes
4b701000.aes
4c000000.emif
-4d000000.emif
-4e000000.dmm
-50000000.gpmc
-52000000.target-module
-55082000.mmu
-5601fc00.target-module
-58000000.dss
-Fixed MDIO bus.0
-a0080000.ramoops
-alarmtimer
-connector
-cpufreq-dt
gpio_keys
-hsusb1_phy
-leds
-omap_dma_system.0
-oprofile-perf.0
-pmu
reg-dummy
-regulator-vdd33a
-regulator-vddvario
-serial8250
-soc
-soc:dsp
-soc:iva
-soc:mpu
-sound
-twl
-twl6040-codec
-twl6040-gpo
-twl6040-pdmclk
w2cbw0015_vmmc
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V4 11/11] docs: arm64: Add layout and 52-bit info to memory document
From: Steve Capper @ 2019-08-07 13:29 UTC (permalink / raw)
To: Catalin Marinas
Cc: crecklin@redhat.com, ard.biesheuvel@linaro.org, maz@kernel.org,
bhsharma@redhat.com, nd, will@kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190806152734.GH30716@arrakis.emea.arm.com>
On Tue, Aug 06, 2019 at 04:27:34PM +0100, Catalin Marinas wrote:
> On Mon, Jul 29, 2019 at 05:21:17PM +0100, Steve Capper wrote:
> > +AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit)::
> >
> > Start End Size Use
> > -----------------------------------------------------------------------
> > 0000000000000000 0000ffffffffffff 256TB user
> > - ffff000000000000 ffffffffffffffff 256TB kernel
> > -
> > -
> > -AArch64 Linux memory layout with 64KB pages + 2 levels::
> > + ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map
> > + ffff800000000000 ffff9fffffffffff 32TB kasan shadow region
> > + ffffa00000000000 ffffa00007ffffff 128MB bpf jit region
> > + ffffa00008000000 ffffa0000fffffff 128MB modules
> > + ffffa00010000000 fffffdffbffeffff ~93TB vmalloc
> > + fffffdffbfff0000 fffffdfffe5f8fff ~998MB [guard region]
> > + fffffdfffe5f9000 fffffdfffe9fffff 4124KB fixed mappings
> > + fffffdfffea00000 fffffdfffebfffff 2MB [guard region]
> > + fffffdfffec00000 fffffdffffbfffff 16MB PCI I/O space
> > + fffffdffffc00000 fffffdffffdfffff 2MB [guard region]
> > + fffffdffffe00000 ffffffffffdfffff 2TB vmemmap
> > + ffffffffffe00000 ffffffffffffffff 2MB [guard region]
> [...]
> > +AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support)::
> >
> > -For details of the virtual kernel memory layout please see the kernel
> > -booting log.
> > + Start End Size Use
> > + -----------------------------------------------------------------------
> > + 0000000000000000 000fffffffffffff 4PB user
> > + fff0000000000000 fff7ffffffffffff 2PB kernel logical memory map
> > + fff8000000000000 fffd9fffffffffff 1440TB [gap]
> > + fffda00000000000 ffff9fffffffffff 512TB kasan shadow region
> > + ffffa00000000000 ffffa00007ffffff 128MB bpf jit region
> > + ffffa00008000000 ffffa0000fffffff 128MB modules
> > + ffffa00010000000 fffff81ffffeffff ~88TB vmalloc
> > + fffff81fffff0000 fffffc1ffe58ffff ~3TB [guard region]
> > + fffffc1ffe590000 fffffc1ffe9fffff 4544KB fixed mappings
> > + fffffc1ffea00000 fffffc1ffebfffff 2MB [guard region]
> > + fffffc1ffec00000 fffffc1fffbfffff 16MB PCI I/O space
> > + fffffc1fffc00000 fffffc1fffdfffff 2MB [guard region]
> > + fffffc1fffe00000 ffffffffffdfffff 3968GB vmemmap
> > + ffffffffffe00000 ffffffffffffffff 2MB [guard region]
>
> Since we risk getting these out of sync, I'd rather only maintain two
> entries: defconfig (4K pages, 48-bit VA) and the largest (64K pages,
> 52-bit with HW support).
>
Sure thing, I've cut down the number of tables to two.
>
> > +52-bit VA support in the kernel
> > +-------------------------------
> > +If the ARMv8.2-LVA optional feature is present, and we are running
> > +with a 64KB page size; then it is possible to use 52-bits of address
> > +space for both userspace and kernel addresses. However, any kernel
> > +binary that supports 52-bit must also be able to fall back to 48-bit
> > +at early boot time if the hardware feature is not present.
> > +
> > +This fallback mechanism necessitates the kernel .text to be in the
> > +higher addresses s.t. they are invariant to 48/52-bti VAs. Due to
>
> The 's.t.' abbreviation always confused me. Could you please change it
> to "so that" in the documentation? (I'm not too bothered about the
> commit logs).
Thanks, I've expanded the acronym.
>
> Also fix s/bti/bit/.
And fixed the typo.
>
> Otherwise:
>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>
Many thanks for going through this series Catalin. Would you like me to post
a V5 of the series?
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] firmware: arm_scmi: Use {get,put}_unaligned_le32 accessors
From: Philipp Zabel @ 2019-08-07 13:36 UTC (permalink / raw)
To: Sudeep Holla, linux-arm-kernel; +Cc: linux-kernel
In-Reply-To: <20190807130038.26878-1-sudeep.holla@arm.com>
Hi Sudeep,
On Wed, 2019-08-07 at 14:00 +0100, Sudeep Holla wrote:
> Instead of type-casting the {tx,rx}.buf all over the place while
> accessing them to read/write __le32 from/to the firmware, let's use
> the nice existing {get,put}_unaligned_le32 accessors to hide all the
> type cast ugliness.
>
> Suggested-by: Philipp Zabel <p.zabel@pengutronix.de>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
> drivers/firmware/arm_scmi/base.c | 2 +-
> drivers/firmware/arm_scmi/clock.c | 10 ++++------
> drivers/firmware/arm_scmi/common.h | 2 ++
> drivers/firmware/arm_scmi/perf.c | 8 ++++----
> drivers/firmware/arm_scmi/power.c | 6 +++---
> drivers/firmware/arm_scmi/reset.c | 2 +-
> drivers/firmware/arm_scmi/sensors.c | 12 +++++-------
> 7 files changed, 20 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
> index 204390297f4b..f804e8af6521 100644
> --- a/drivers/firmware/arm_scmi/base.c
> +++ b/drivers/firmware/arm_scmi/base.c
[...]
> @@ -204,14 +204,12 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
> if (ret)
> return ret;
>
> - *(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
> + put_unaligned_le32(clk_id, t->tx.buf);
>
> ret = scmi_do_xfer(handle, t);
> if (!ret) {
> - __le32 *pval = t->rx.buf;
> -
> - *value = le32_to_cpu(*pval);
> - *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
> + *value = get_unaligned_le32(t->rx.buf);
> + *value |= (u64)get_unaligned_le32(t->rx.buf + 1) << 32;
Isn't t->rx.buf a void pointer? If I am not mistaken, you'd either have
to keep the pval local variables, or cast to (__le32 *) before doing
pointer arithmetic.
regards
Philipp
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 04/14] media: rkisp1: add Rockchip MIPI Synopsys DPHY driver
From: Helen Koike @ 2019-08-07 13:37 UTC (permalink / raw)
To: Sakari Ailus
Cc: devicetree, eddie.cai.linux, kernel, heiko, jacob2.chen,
jeffy.chen, zyc, linux-kernel, tfiga, linux-rockchip,
hans.verkuil, laurent.pinchart, sakari.ailus, zhengsq, mchehab,
ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <20190807130558.GF822@valkosipuli.retiisi.org.uk>
Hi Sakari,
thanks for your review,
On 8/7/19 10:05 AM, Sakari Ailus wrote:
> Hi Helen,
>
> Thanks for the patchset.
>
> On Tue, Jul 30, 2019 at 03:42:46PM -0300, Helen Koike wrote:
>> From: Jacob Chen <jacob2.chen@rock-chips.com>
>>
>> This commit adds a subdev driver for Rockchip MIPI Synopsys DPHY driver
>>
>> Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
>> Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com>
>> Signed-off-by: Tomasz Figa <tfiga@chromium.org>
>> [migrate to phy framework]
>> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
>> [update for upstream]
>> Signed-off-by: Helen Koike <helen.koike@collabora.com>
>>
>> ---
>>
>> Changes in v8:
>> - Remove boiler plate license text
>>
>> Changes in v7:
>> - Migrate dphy specific code from
>> drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
>> to drivers/phy/rockchip/phy-rockchip-dphy.c
>> - Drop support for rk3288
>> - Drop support for dphy txrx
>> - code styling and checkpatch fixes
>>
>> drivers/phy/rockchip/Kconfig | 8 +
>> drivers/phy/rockchip/Makefile | 1 +
>> drivers/phy/rockchip/phy-rockchip-dphy.c | 408 +++++++++++++++++++++++
>> 3 files changed, 417 insertions(+)
>> create mode 100644 drivers/phy/rockchip/phy-rockchip-dphy.c
>>
>> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
>> index c454c90cd99e..afd072f135e6 100644
>> --- a/drivers/phy/rockchip/Kconfig
>> +++ b/drivers/phy/rockchip/Kconfig
>> @@ -9,6 +9,14 @@ config PHY_ROCKCHIP_DP
>> help
>> Enable this to support the Rockchip Display Port PHY.
>>
>> +config PHY_ROCKCHIP_DPHY
>> + tristate "Rockchip MIPI Synopsys DPHY driver"
>> + depends on ARCH_ROCKCHIP && OF
>
> How about (...) || COMPILE_TEST ?
>
>> + select GENERIC_PHY_MIPI_DPHY
>> + select GENERIC_PHY
>> + help
>> + Enable this to support the Rockchip MIPI Synopsys DPHY.
>> +
>> config PHY_ROCKCHIP_EMMC
>> tristate "Rockchip EMMC PHY Driver"
>> depends on ARCH_ROCKCHIP && OF
>> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
>> index fd21cbaf40dd..f62e9010bcaf 100644
>> --- a/drivers/phy/rockchip/Makefile
>> +++ b/drivers/phy/rockchip/Makefile
>> @@ -1,5 +1,6 @@
>> # SPDX-License-Identifier: GPL-2.0
>> obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
>> +obj-$(CONFIG_PHY_ROCKCHIP_DPHY) += phy-rockchip-dphy.o
>> obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
>> obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o
>> obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
>> diff --git a/drivers/phy/rockchip/phy-rockchip-dphy.c b/drivers/phy/rockchip/phy-rockchip-dphy.c
>> new file mode 100644
>> index 000000000000..3a29976c2dff
>> --- /dev/null
>> +++ b/drivers/phy/rockchip/phy-rockchip-dphy.c
>> @@ -0,0 +1,408 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Rockchip MIPI Synopsys DPHY driver
>> + *
>> + * Based on:
>> + *
>> + * Copyright (C) 2016 FuZhou Rockchip Co., Ltd.
>> + * Author: Yakir Yang <ykk@@rock-chips.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/phy/phy-mipi-dphy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#define RK3399_GRF_SOC_CON9 0x6224
>> +#define RK3399_GRF_SOC_CON21 0x6254
>> +#define RK3399_GRF_SOC_CON22 0x6258
>> +#define RK3399_GRF_SOC_CON23 0x625c
>> +#define RK3399_GRF_SOC_CON24 0x6260
>> +#define RK3399_GRF_SOC_CON25 0x6264
>> +#define RK3399_GRF_SOC_STATUS1 0xe2a4
>> +
>> +#define CLOCK_LANE_HS_RX_CONTROL 0x34
>> +#define LANE0_HS_RX_CONTROL 0x44
>> +#define LANE1_HS_RX_CONTROL 0x54
>> +#define LANE2_HS_RX_CONTROL 0x84
>> +#define LANE3_HS_RX_CONTROL 0x94
>> +#define HS_RX_DATA_LANES_THS_SETTLE_CONTROL 0x75
>> +
>> +#define MAX_DPHY_CLK 8
>> +
>> +#define PHY_TESTEN_ADDR (0x1 << 16)
>> +#define PHY_TESTEN_DATA (0x0 << 16)
>> +#define PHY_TESTCLK (0x1 << 1)
>> +#define PHY_TESTCLR (0x1 << 0)
>> +#define THS_SETTLE_COUNTER_THRESHOLD 0x04
>> +
>> +#define HIWORD_UPDATE(val, mask, shift) \
>> + ((val) << (shift) | (mask) << ((shift) + 16))
>> +
>> +#define GRF_SOC_CON12 0x0274
>> +
>> +#define GRF_EDP_REF_CLK_SEL_INTER_HIWORD_MASK BIT(20)
>> +#define GRF_EDP_REF_CLK_SEL_INTER BIT(4)
>> +
>> +#define GRF_EDP_PHY_SIDDQ_HIWORD_MASK BIT(21)
>> +#define GRF_EDP_PHY_SIDDQ_ON 0
>> +#define GRF_EDP_PHY_SIDDQ_OFF BIT(5)
>> +
>> +struct hsfreq_range {
>> + u32 range_h;
>> + u8 cfg_bit;
>> +};
>> +
>> +static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
>> + { 89, 0x00}, { 99, 0x10}, { 109, 0x20}, { 129, 0x01},
>> + { 139, 0x11}, { 149, 0x21}, { 169, 0x02}, { 179, 0x12},
>> + { 199, 0x22}, { 219, 0x03}, { 239, 0x13}, { 249, 0x23},
>> + { 269, 0x04}, { 299, 0x14}, { 329, 0x05}, { 359, 0x15},
>> + { 399, 0x25}, { 449, 0x06}, { 499, 0x16}, { 549, 0x07},
>> + { 599, 0x17}, { 649, 0x08}, { 699, 0x18}, { 749, 0x09},
>> + { 799, 0x19}, { 849, 0x29}, { 899, 0x39}, { 949, 0x0a},
>> + { 999, 0x1a}, {1049, 0x2a}, {1099, 0x3a}, {1149, 0x0b},
>> + {1199, 0x1b}, {1249, 0x2b}, {1299, 0x3b}, {1349, 0x0c},
>> + {1399, 0x1c}, {1449, 0x2c}, {1500, 0x3c}
>> +};
>> +
>> +static const char * const rk3399_mipidphy_clks[] = {
>> + "dphy-ref",
>> + "dphy-cfg",
>> + "grf",
>> +};
>> +
>> +enum dphy_reg_id {
>> + GRF_DPHY_RX0_TURNDISABLE = 0,
>> + GRF_DPHY_RX0_FORCERXMODE,
>> + GRF_DPHY_RX0_FORCETXSTOPMODE,
>> + GRF_DPHY_RX0_ENABLE,
>> + GRF_DPHY_RX0_TESTCLR,
>> + GRF_DPHY_RX0_TESTCLK,
>> + GRF_DPHY_RX0_TESTEN,
>> + GRF_DPHY_RX0_TESTDIN,
>> + GRF_DPHY_RX0_TURNREQUEST,
>> + GRF_DPHY_RX0_TESTDOUT,
>> + GRF_DPHY_TX0_TURNDISABLE,
>> + GRF_DPHY_TX0_FORCERXMODE,
>> + GRF_DPHY_TX0_FORCETXSTOPMODE,
>> + GRF_DPHY_TX0_TURNREQUEST,
>> + GRF_DPHY_TX1RX1_TURNDISABLE,
>> + GRF_DPHY_TX1RX1_FORCERXMODE,
>> + GRF_DPHY_TX1RX1_FORCETXSTOPMODE,
>> + GRF_DPHY_TX1RX1_ENABLE,
>> + GRF_DPHY_TX1RX1_MASTERSLAVEZ,
>> + GRF_DPHY_TX1RX1_BASEDIR,
>> + GRF_DPHY_TX1RX1_ENABLECLK,
>> + GRF_DPHY_TX1RX1_TURNREQUEST,
>> + GRF_DPHY_RX1_SRC_SEL,
>> + /* rk3288 only */
>> + GRF_CON_DISABLE_ISP,
>> + GRF_CON_ISP_DPHY_SEL,
>> + GRF_DSI_CSI_TESTBUS_SEL,
>> + GRF_DVP_V18SEL,
>> + /* below is for rk3399 only */
>> + GRF_DPHY_RX0_CLK_INV_SEL,
>> + GRF_DPHY_RX1_CLK_INV_SEL,
>> +};
>> +
>> +struct dphy_reg {
>> + u32 offset;
>> + u32 mask;
>> + u32 shift;
>> +};
>> +
>> +#define PHY_REG(_offset, _width, _shift) \
>> + { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
>> +
>> +static const struct dphy_reg rk3399_grf_dphy_regs[] = {
>> + [GRF_DPHY_RX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON9, 4, 0),
>> + [GRF_DPHY_RX0_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 10),
>> + [GRF_DPHY_RX1_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 11),
>> + [GRF_DPHY_RX0_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 0),
>> + [GRF_DPHY_RX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 4),
>> + [GRF_DPHY_RX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 8),
>> + [GRF_DPHY_RX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 12),
>> + [GRF_DPHY_TX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 0),
>> + [GRF_DPHY_TX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 4),
>> + [GRF_DPHY_TX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 8),
>> + [GRF_DPHY_TX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 12),
>> + [GRF_DPHY_TX1RX1_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 0),
>> + [GRF_DPHY_TX1RX1_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 4),
>> + [GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
>> + [GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
>> + [GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
>> + [GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
>> + [GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
>> + [GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
>> + [GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
>> + [GRF_DPHY_RX0_TESTDIN] = PHY_REG(RK3399_GRF_SOC_CON25, 8, 0),
>> + [GRF_DPHY_RX0_TESTEN] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 8),
>> + [GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
>> + [GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
>> + [GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
>> +};
>> +
>> +struct dphy_drv_data {
>> + const char * const *clks;
>> + int num_clks;
>> + const struct hsfreq_range *hsfreq_ranges;
>> + int num_hsfreq_ranges;
>> + const struct dphy_reg *regs;
>> +};
>> +
>> +struct rockchip_dphy {
>> + struct device *dev;
>> + struct regmap *grf;
>> + const struct dphy_reg *grf_regs;
>> + struct clk_bulk_data clks[MAX_DPHY_CLK];
>> +
>> + const struct dphy_drv_data *drv_data;
>> + struct phy_configure_opts_mipi_dphy config;
>> +};
>> +
>> +static inline void write_grf_reg(struct rockchip_dphy *priv,
>> + int index, u8 value)
>> +{
>> + const struct dphy_reg *reg = &priv->grf_regs[index];
>> + unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
>> +
>> + WARN_ON(!reg->offset);
>> + regmap_write(priv->grf, reg->offset, val);
>> +}
>> +
>> +static void mipidphy0_wr_reg(struct rockchip_dphy *priv,
>> + u8 test_code, u8 test_data)
>> +{
>> + /*
>> + * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
>> + * is latched internally as the current test code. Test data is
>> + * programmed internally by rising edge on TESTCLK.
>> + */
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTDIN, test_code);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTEN, 1);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 0);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTEN, 0);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTDIN, test_data);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
>> +}
>> +
>> +/* should be move to power_on */
>> +static int mipidphy_rx_stream_on(struct rockchip_dphy *priv)
>> +{
>> + const struct dphy_drv_data *drv_data = priv->drv_data;
>> + const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges;
>> + struct phy_configure_opts_mipi_dphy *config = &priv->config;
>> + unsigned int i, hsfreq = 0, data_rate_mbps = config->hs_clk_rate;
>> + int num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
>> +
>> + do_div(data_rate_mbps, 1000 * 1000);
>> +
>> + dev_dbg(priv->dev, "%s: lanes %d - data_rate_mbps %u\n",
>> + __func__, config->lanes, data_rate_mbps);
>> +
>> + for (i = 0; i < num_hsfreq_ranges; i++) {
>> + if (hsfreq_ranges[i].range_h >= data_rate_mbps) {
>> + hsfreq = hsfreq_ranges[i].cfg_bit;
>> + break;
>> + }
>> + }
>> +
>> + write_grf_reg(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
>> + write_grf_reg(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
>> +
>> + /* Disable lan turn around, which is ignored in receive mode */
>> + write_grf_reg(priv, GRF_DPHY_RX0_TURNREQUEST, 0);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TURNDISABLE, 0xf);
>> +
>> + write_grf_reg(priv, GRF_DPHY_RX0_ENABLE, GENMASK(config->lanes - 1, 0));
>> +
>> + /* dphy start */
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLK, 1);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLR, 1);
>> + usleep_range(100, 150);
>> + write_grf_reg(priv, GRF_DPHY_RX0_TESTCLR, 0);
>> + usleep_range(100, 150);
>> +
>> + /* set clock lane */
>> + /* HS hsfreq_range & lane 0 settle bypass */
>> + mipidphy0_wr_reg(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
>> + /* HS RX Control of lane0 */
>> + mipidphy0_wr_reg(priv, LANE0_HS_RX_CONTROL, hsfreq << 1);
>> + /* HS RX Control of lane1 */
>> + mipidphy0_wr_reg(priv, LANE1_HS_RX_CONTROL, 0);
>> + /* HS RX Control of lane2 */
>> + mipidphy0_wr_reg(priv, LANE2_HS_RX_CONTROL, 0);
>> + /* HS RX Control of lane3 */
>> + mipidphy0_wr_reg(priv, LANE3_HS_RX_CONTROL, 0);
>> + /* HS RX Data Lanes Settle State Time Control */
>> + mipidphy0_wr_reg(priv, HS_RX_DATA_LANES_THS_SETTLE_CONTROL,
>> + THS_SETTLE_COUNTER_THRESHOLD);
>> +
>> + /* Normal operation */
>> + mipidphy0_wr_reg(priv, 0x0, 0);
>> +
>> + return 0;
>> +}
>> +
>> +static int rockchip_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
>> +{
>> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + /* pass with phy_mipi_dphy_get_default_config (with pixel rate?) */
>> + ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
>> + if (ret)
>> + return ret;
>> +
>> + memcpy(&priv->config, opts, sizeof(priv->config));
>
> You could to:
>
> priv->config = *opts;
>
> Up to you. Some people like memcpy(). :-)
your way is better thanks!
>
>> +
>> + return 0;
>> +}
>> +
>> +static int rockchip_dphy_power_on(struct phy *phy)
>> +{
>> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + ret = clk_bulk_enable(priv->drv_data->num_clks, priv->clks);
>> + if (ret)
>> + return ret;
>> +
>> + return mipidphy_rx_stream_on(priv);
>> +}
>> +
>> +static int rockchip_dphy_power_off(struct phy *phy)
>> +{
>> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
>> +
>> + clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
>> + return 0;
>> +}
>> +
>> +static int rockchip_dphy_init(struct phy *phy)
>> +{
>> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + ret = clk_bulk_prepare(priv->drv_data->num_clks, priv->clks);
>
> return ...;
>
>> + if (ret)
>> + return ret;
>> + return 0;
>> +}
>> +
>> +static int rockchip_dphy_exit(struct phy *phy)
>> +{
>> + struct rockchip_dphy *priv = phy_get_drvdata(phy);
>> +
>> + clk_bulk_unprepare(priv->drv_data->num_clks, priv->clks);
>> + return 0;
>> +}
>> +
>> +static const struct phy_ops rockchip_dphy_ops = {
>> + .power_on = rockchip_dphy_power_on,
>> + .power_off = rockchip_dphy_power_off,
>> + .init = rockchip_dphy_init,
>> + .exit = rockchip_dphy_exit,
>> + .configure = rockchip_dphy_configure,
>> + .owner = THIS_MODULE,
>> +};
>> +
>> +static const struct dphy_drv_data rk3399_mipidphy_drv_data = {
>> + .clks = rk3399_mipidphy_clks,
>> + .num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
>> + .hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
>> + .num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
>> + .regs = rk3399_grf_dphy_regs,
>
> Do you expect to support more of the similar PHY(s) --- are there such? If
> not, you could put these in the code that uses them.
Yes, for rk3288 in the future.
Regards,
Helen
>
>> +};
>> +
>> +static const struct of_device_id rockchip_dphy_dt_ids[] = {
>> + {
>> + .compatible = "rockchip,rk3399-mipi-dphy",
>> + .data = &rk3399_mipidphy_drv_data,
>> + },
>> + {}
>> +};
>> +MODULE_DEVICE_TABLE(of, rockchip_dphy_dt_ids);
>> +
>> +static int rockchip_dphy_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct device_node *np = dev->of_node;
>> + const struct dphy_drv_data *drv_data;
>> + struct phy_provider *phy_provider;
>> + const struct of_device_id *of_id;
>> + struct rockchip_dphy *priv;
>> + struct regmap *grf;
>> + struct phy *phy;
>> + unsigned int i;
>> + int ret;
>> +
>> + if (!dev->parent || !dev->parent->of_node)
>> + return -ENODEV;
>> +
>> + if (platform_get_resource(pdev, IORESOURCE_MEM, 0)) {
>> + dev_err(&pdev->dev, "Rockchip DPHY driver only suports rx\n");
>> + return -EINVAL;
>> + }
>> +
>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv)
>> + return -ENOMEM;
>> + priv->dev = dev;
>> +
>> + grf = syscon_node_to_regmap(dev->parent->of_node);
>> + if (IS_ERR(grf)) {
>> + grf = syscon_regmap_lookup_by_phandle(dev->of_node,
>> + "rockchip,grf");
>> + if (IS_ERR(grf)) {
>> + dev_err(dev, "Can't find GRF syscon\n");
>> + return -ENODEV;
>> + }
>> + }
>> + priv->grf = grf;
>> +
>> + of_id = of_match_device(rockchip_dphy_dt_ids, dev);
>> + if (!of_id)
>> + return -EINVAL;
>> +
>> + drv_data = of_id->data;
>> + priv->grf_regs = drv_data->regs;
>> + priv->drv_data = drv_data;
>> + for (i = 0; i < drv_data->num_clks; i++)
>> + priv->clks[i].id = drv_data->clks[i];
>> + ret = devm_clk_bulk_get(&pdev->dev, drv_data->num_clks, priv->clks);
>> + if (ret)
>> + return ret;
>> +
>> + phy = devm_phy_create(dev, np, &rockchip_dphy_ops);
>> + if (IS_ERR(phy)) {
>> + dev_err(dev, "failed to create phy\n");
>> + return PTR_ERR(phy);
>> + }
>> + phy_set_drvdata(phy, priv);
>> +
>> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>> +
>> + return PTR_ERR_OR_ZERO(phy_provider);
>> +}
>> +
>> +static struct platform_driver rockchip_dphy_driver = {
>> + .probe = rockchip_dphy_probe,
>> + .driver = {
>> + .name = "rockchip-mipi-dphy",
>> + .of_match_table = rockchip_dphy_dt_ids,
>> + },
>> +};
>> +module_platform_driver(rockchip_dphy_driver);
>> +
>> +MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
>> +MODULE_DESCRIPTION("Rockchip MIPI Synopsys DPHY driver");
>> +MODULE_LICENSE("Dual MIT/GPL");
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v5 1/4] devfreq: exynos-bus: correct clock enable sequence
From: k.konieczny @ 2019-08-07 13:38 UTC (permalink / raw)
To: k.konieczny
Cc: Mark Rutland, Nishanth Menon, linux-samsung-soc, Rob Herring,
linux-arm-kernel, Bartlomiej Zolnierkiewicz, Stephen Boyd,
Viresh Kumar, linux-pm, linux-kernel, Krzysztof Kozlowski,
Chanwoo Choi, Kyungmin Park, Kukjin Kim, MyungJoo Ham, devicetree,
Marek Szyprowski
In-Reply-To: <20190807133838.14678-1-k.konieczny@partner.samsung.com>
Regulators should be enabled before clocks to avoid h/w hang. This
require change in exynos_bus_probe() to move exynos_bus_parse_of()
after exynos_bus_parent_parse_of() and change in error handling.
Similar change is needed in exynos_bus_exit() where clock should be
disabled before regulators.
Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes:
v5:
- added Acked-by tag
v4:
- move regulator disable after clock disable
- remove unrelated changes
- add disabling regulators in error path in exynos_bus_probe()
---
drivers/devfreq/exynos-bus.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 486cc5b422f1..f34fa26f00d0 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -194,11 +194,10 @@ static void exynos_bus_exit(struct device *dev)
if (ret < 0)
dev_warn(dev, "failed to disable the devfreq-event devices\n");
- if (bus->regulator)
- regulator_disable(bus->regulator);
-
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
+ if (bus->regulator)
+ regulator_disable(bus->regulator);
}
/*
@@ -386,6 +385,7 @@ static int exynos_bus_probe(struct platform_device *pdev)
struct exynos_bus *bus;
int ret, max_state;
unsigned long min_freq, max_freq;
+ bool passive = false;
if (!np) {
dev_err(dev, "failed to find devicetree node\n");
@@ -399,27 +399,27 @@ static int exynos_bus_probe(struct platform_device *pdev)
bus->dev = &pdev->dev;
platform_set_drvdata(pdev, bus);
- /* Parse the device-tree to get the resource information */
- ret = exynos_bus_parse_of(np, bus);
- if (ret < 0)
- return ret;
-
profile = devm_kzalloc(dev, sizeof(*profile), GFP_KERNEL);
- if (!profile) {
- ret = -ENOMEM;
- goto err;
- }
+ if (!profile)
+ return -ENOMEM;
node = of_parse_phandle(dev->of_node, "devfreq", 0);
if (node) {
of_node_put(node);
- goto passive;
+ passive = true;
} else {
ret = exynos_bus_parent_parse_of(np, bus);
+ if (ret < 0)
+ return ret;
}
+ /* Parse the device-tree to get the resource information */
+ ret = exynos_bus_parse_of(np, bus);
if (ret < 0)
- goto err;
+ goto err_reg;
+
+ if (passive)
+ goto passive;
/* Initialize the struct profile and governor data for parent device */
profile->polling_ms = 50;
@@ -510,6 +510,9 @@ static int exynos_bus_probe(struct platform_device *pdev)
err:
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
+err_reg:
+ if (!passive)
+ regulator_disable(bus->regulator);
return ret;
}
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v5 4/4] dt-bindings: devfreq: exynos-bus: remove unused property
From: k.konieczny @ 2019-08-07 13:38 UTC (permalink / raw)
To: k.konieczny
Cc: Mark Rutland, Nishanth Menon, linux-samsung-soc, Rob Herring,
linux-arm-kernel, Bartlomiej Zolnierkiewicz, Stephen Boyd,
Viresh Kumar, linux-pm, linux-kernel, Krzysztof Kozlowski,
Chanwoo Choi, Kyungmin Park, Kukjin Kim, MyungJoo Ham, devicetree,
Marek Szyprowski
In-Reply-To: <20190807133838.14678-1-k.konieczny@partner.samsung.com>
Remove unused DT property "exynos,voltage-tolerance".
Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Documentation/devicetree/bindings/devfreq/exynos-bus.txt | 2 --
1 file changed, 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index f8e946471a58..e71f752cc18f 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -50,8 +50,6 @@ Required properties only for passive bus device:
Optional properties only for parent bus device:
- exynos,saturation-ratio: the percentage value which is used to calibrate
the performance count against total cycle count.
-- exynos,voltage-tolerance: the percentage value for bus voltage tolerance
- which is used to calculate the max voltage.
Detailed correlation between sub-blocks and power line according to Exynos SoC:
- In case of Exynos3250, there are two power line as following:
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v5 3/4] ARM: dts: exynos: add initial data for coupled regulators for Exynos5422/5800
From: k.konieczny @ 2019-08-07 13:38 UTC (permalink / raw)
To: k.konieczny
Cc: Mark Rutland, Nishanth Menon, linux-samsung-soc, Rob Herring,
linux-arm-kernel, Bartlomiej Zolnierkiewicz, Stephen Boyd,
Viresh Kumar, linux-pm, linux-kernel, Krzysztof Kozlowski,
Chanwoo Choi, Kyungmin Park, Kukjin Kim, MyungJoo Ham, devicetree,
Marek Szyprowski
In-Reply-To: <20190807133838.14678-1-k.konieczny@partner.samsung.com>
From: Marek Szyprowski <m.szyprowski@samsung.com>
Declare Exynos5422/5800 voltage ranges for opp points for big cpu core and
bus wcore and couple their voltage supllies as vdd_arm and vdd_int should
be in 300mV range.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[k.konieczny: add missing patch description]
Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
---
arch/arm/boot/dts/exynos5420.dtsi | 34 +++++++++----------
arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 4 +++
arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++
arch/arm/boot/dts/exynos5800.dtsi | 32 ++++++++---------
4 files changed, 41 insertions(+), 33 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 5fb2326875dc..0cbf74750553 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -48,62 +48,62 @@
opp-shared;
opp-1800000000 {
opp-hz = /bits/ 64 <1800000000>;
- opp-microvolt = <1250000>;
+ opp-microvolt = <1250000 1250000 1500000>;
clock-latency-ns = <140000>;
};
opp-1700000000 {
opp-hz = /bits/ 64 <1700000000>;
- opp-microvolt = <1212500>;
+ opp-microvolt = <1212500 1212500 1500000>;
clock-latency-ns = <140000>;
};
opp-1600000000 {
opp-hz = /bits/ 64 <1600000000>;
- opp-microvolt = <1175000>;
+ opp-microvolt = <1175000 1175000 1500000>;
clock-latency-ns = <140000>;
};
opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
- opp-microvolt = <1137500>;
+ opp-microvolt = <1137500 1137500 1500000>;
clock-latency-ns = <140000>;
};
opp-1400000000 {
opp-hz = /bits/ 64 <1400000000>;
- opp-microvolt = <1112500>;
+ opp-microvolt = <1112500 1112500 1500000>;
clock-latency-ns = <140000>;
};
opp-1300000000 {
opp-hz = /bits/ 64 <1300000000>;
- opp-microvolt = <1062500>;
+ opp-microvolt = <1062500 1062500 1500000>;
clock-latency-ns = <140000>;
};
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
- opp-microvolt = <1037500>;
+ opp-microvolt = <1037500 1037500 1500000>;
clock-latency-ns = <140000>;
};
opp-1100000000 {
opp-hz = /bits/ 64 <1100000000>;
- opp-microvolt = <1012500>;
+ opp-microvolt = <1012500 1012500 1500000>;
clock-latency-ns = <140000>;
};
opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
- opp-microvolt = < 987500>;
+ opp-microvolt = < 987500 987500 1500000>;
clock-latency-ns = <140000>;
};
opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
- opp-microvolt = < 962500>;
+ opp-microvolt = < 962500 962500 1500000>;
clock-latency-ns = <140000>;
};
opp-800000000 {
opp-hz = /bits/ 64 <800000000>;
- opp-microvolt = < 937500>;
+ opp-microvolt = < 937500 937500 1500000>;
clock-latency-ns = <140000>;
};
opp-700000000 {
opp-hz = /bits/ 64 <700000000>;
- opp-microvolt = < 912500>;
+ opp-microvolt = < 912500 912500 1500000>;
clock-latency-ns = <140000>;
};
};
@@ -1100,23 +1100,23 @@
opp00 {
opp-hz = /bits/ 64 <84000000>;
- opp-microvolt = <925000>;
+ opp-microvolt = <925000 925000 1400000>;
};
opp01 {
opp-hz = /bits/ 64 <111000000>;
- opp-microvolt = <950000>;
+ opp-microvolt = <950000 950000 1400000>;
};
opp02 {
opp-hz = /bits/ 64 <222000000>;
- opp-microvolt = <950000>;
+ opp-microvolt = <950000 950000 1400000>;
};
opp03 {
opp-hz = /bits/ 64 <333000000>;
- opp-microvolt = <950000>;
+ opp-microvolt = <950000 950000 1400000>;
};
opp04 {
opp-hz = /bits/ 64 <400000000>;
- opp-microvolt = <987500>;
+ opp-microvolt = <987500 987500 1400000>;
};
};
diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
index 25d95de15c9b..65d094256b54 100644
--- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
@@ -428,6 +428,8 @@
regulator-max-microvolt = <1500000>;
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&buck3_reg>;
+ regulator-coupled-max-spread = <300000>;
};
buck3_reg: BUCK3 {
@@ -436,6 +438,8 @@
regulator-max-microvolt = <1400000>;
regulator-always-on;
regulator-boot-on;
+ regulator-coupled-with = <&buck2_reg>;
+ regulator-coupled-max-spread = <300000>;
};
buck4_reg: BUCK4 {
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index e0f470fe54c8..5c1e965ed7e9 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -257,6 +257,8 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-coupled-with = <&buck3_reg>;
+ regulator-coupled-max-spread = <300000>;
regulator-state-mem {
regulator-off-in-suspend;
};
@@ -269,6 +271,8 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-coupled-with = <&buck2_reg>;
+ regulator-coupled-max-spread = <300000>;
regulator-state-mem {
regulator-off-in-suspend;
};
diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi
index 57d3b319fd65..2a74735d161c 100644
--- a/arch/arm/boot/dts/exynos5800.dtsi
+++ b/arch/arm/boot/dts/exynos5800.dtsi
@@ -22,61 +22,61 @@
&cluster_a15_opp_table {
opp-1700000000 {
- opp-microvolt = <1250000>;
+ opp-microvolt = <1250000 1250000 1500000>;
};
opp-1600000000 {
- opp-microvolt = <1250000>;
+ opp-microvolt = <1250000 1250000 1500000>;
};
opp-1500000000 {
- opp-microvolt = <1100000>;
+ opp-microvolt = <1100000 1100000 1500000>;
};
opp-1400000000 {
- opp-microvolt = <1100000>;
+ opp-microvolt = <1100000 1100000 1500000>;
};
opp-1300000000 {
- opp-microvolt = <1100000>;
+ opp-microvolt = <1100000 1100000 1500000>;
};
opp-1200000000 {
- opp-microvolt = <1000000>;
+ opp-microvolt = <1000000 1000000 1500000>;
};
opp-1100000000 {
- opp-microvolt = <1000000>;
+ opp-microvolt = <1000000 1000000 1500000>;
};
opp-1000000000 {
- opp-microvolt = <1000000>;
+ opp-microvolt = <1000000 1000000 1500000>;
};
opp-900000000 {
- opp-microvolt = <1000000>;
+ opp-microvolt = <1000000 1000000 1500000>;
};
opp-800000000 {
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
};
opp-700000000 {
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
};
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
clock-latency-ns = <140000>;
};
opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
clock-latency-ns = <140000>;
};
opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
clock-latency-ns = <140000>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
clock-latency-ns = <140000>;
};
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <900000 900000 1500000>;
clock-latency-ns = <140000>;
};
};
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v5 2/4] devfreq: exynos-bus: convert to use dev_pm_opp_set_rate()
From: k.konieczny @ 2019-08-07 13:38 UTC (permalink / raw)
To: k.konieczny
Cc: Mark Rutland, Nishanth Menon, linux-samsung-soc, Rob Herring,
linux-arm-kernel, Bartlomiej Zolnierkiewicz, Stephen Boyd,
Viresh Kumar, linux-pm, linux-kernel, Krzysztof Kozlowski,
Chanwoo Choi, Kyungmin Park, Kukjin Kim, MyungJoo Ham, devicetree,
Marek Szyprowski
In-Reply-To: <20190807133838.14678-1-k.konieczny@partner.samsung.com>
Reuse opp core code for setting bus clock and voltage. As a side
effect this allow usage of coupled regulators feature (required
for boards using Exynos5422/5800 SoCs) because dev_pm_opp_set_rate()
uses regulator_set_voltage_triplet() for setting regulator voltage
while the old code used regulator_set_voltage_tol() with fixed
tolerance. This patch also removes no longer needed parsing of DT
property "exynos,voltage-tolerance" (no Exynos devfreq DT node uses
it). After applying changes both functions exynos_bus_passive_target()
and exynos_bus_target() have the same code, so remove
exynos_bus_passive_target(). In exynos_bus_probe() replace it with
exynos_bus_target.
Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
---
Changes:
v5:
- squashed last patch into this one, as suggested by Chanwoo Choi
v4:
- remove unrelated changes, add newline before comment
---
drivers/devfreq/exynos-bus.c | 130 +++++++----------------------------
1 file changed, 24 insertions(+), 106 deletions(-)
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index f34fa26f00d0..2aeb6cc07960 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#define DEFAULT_SATURATION_RATIO 40
-#define DEFAULT_VOLTAGE_TOLERANCE 2
struct exynos_bus {
struct device *dev;
@@ -37,9 +36,8 @@ struct exynos_bus {
unsigned long curr_freq;
- struct regulator *regulator;
+ struct opp_table *opp_table;
struct clk *clk;
- unsigned int voltage_tolerance;
unsigned int ratio;
};
@@ -93,62 +91,29 @@ static int exynos_bus_get_event(struct exynos_bus *bus,
}
/*
- * Must necessary function for devfreq simple-ondemand governor
+ * devfreq function for both simple-ondemand and passive governor
*/
static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
{
struct exynos_bus *bus = dev_get_drvdata(dev);
struct dev_pm_opp *new_opp;
- unsigned long old_freq, new_freq, new_volt, tol;
int ret = 0;
- /* Get new opp-bus instance according to new bus clock */
+ /* Get correct frequency for bus. */
new_opp = devfreq_recommended_opp(dev, freq, flags);
if (IS_ERR(new_opp)) {
dev_err(dev, "failed to get recommended opp instance\n");
return PTR_ERR(new_opp);
}
- new_freq = dev_pm_opp_get_freq(new_opp);
- new_volt = dev_pm_opp_get_voltage(new_opp);
dev_pm_opp_put(new_opp);
- old_freq = bus->curr_freq;
-
- if (old_freq == new_freq)
- return 0;
- tol = new_volt * bus->voltage_tolerance / 100;
-
/* Change voltage and frequency according to new OPP level */
mutex_lock(&bus->lock);
+ ret = dev_pm_opp_set_rate(dev, *freq);
+ if (!ret)
+ bus->curr_freq = *freq;
- if (old_freq < new_freq) {
- ret = regulator_set_voltage_tol(bus->regulator, new_volt, tol);
- if (ret < 0) {
- dev_err(bus->dev, "failed to set voltage\n");
- goto out;
- }
- }
-
- ret = clk_set_rate(bus->clk, new_freq);
- if (ret < 0) {
- dev_err(dev, "failed to change clock of bus\n");
- clk_set_rate(bus->clk, old_freq);
- goto out;
- }
-
- if (old_freq > new_freq) {
- ret = regulator_set_voltage_tol(bus->regulator, new_volt, tol);
- if (ret < 0) {
- dev_err(bus->dev, "failed to set voltage\n");
- goto out;
- }
- }
- bus->curr_freq = new_freq;
-
- dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
- old_freq, new_freq, clk_get_rate(bus->clk));
-out:
mutex_unlock(&bus->lock);
return ret;
@@ -196,54 +161,10 @@ static void exynos_bus_exit(struct device *dev)
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
- if (bus->regulator)
- regulator_disable(bus->regulator);
-}
-
-/*
- * Must necessary function for devfreq passive governor
- */
-static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
- u32 flags)
-{
- struct exynos_bus *bus = dev_get_drvdata(dev);
- struct dev_pm_opp *new_opp;
- unsigned long old_freq, new_freq;
- int ret = 0;
-
- /* Get new opp-bus instance according to new bus clock */
- new_opp = devfreq_recommended_opp(dev, freq, flags);
- if (IS_ERR(new_opp)) {
- dev_err(dev, "failed to get recommended opp instance\n");
- return PTR_ERR(new_opp);
- }
-
- new_freq = dev_pm_opp_get_freq(new_opp);
- dev_pm_opp_put(new_opp);
-
- old_freq = bus->curr_freq;
-
- if (old_freq == new_freq)
- return 0;
-
- /* Change the frequency according to new OPP level */
- mutex_lock(&bus->lock);
-
- ret = clk_set_rate(bus->clk, new_freq);
- if (ret < 0) {
- dev_err(dev, "failed to set the clock of bus\n");
- goto out;
+ if (bus->opp_table) {
+ dev_pm_opp_put_regulators(bus->opp_table);
+ bus->opp_table = NULL;
}
-
- *freq = new_freq;
- bus->curr_freq = new_freq;
-
- dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
- old_freq, new_freq, clk_get_rate(bus->clk));
-out:
- mutex_unlock(&bus->lock);
-
- return ret;
}
static void exynos_bus_passive_exit(struct device *dev)
@@ -258,21 +179,19 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
struct exynos_bus *bus)
{
struct device *dev = bus->dev;
+ struct opp_table *opp_table;
+ const char *vdd = "vdd";
int i, ret, count, size;
- /* Get the regulator to provide each bus with the power */
- bus->regulator = devm_regulator_get(dev, "vdd");
- if (IS_ERR(bus->regulator)) {
- dev_err(dev, "failed to get VDD regulator\n");
- return PTR_ERR(bus->regulator);
- }
-
- ret = regulator_enable(bus->regulator);
- if (ret < 0) {
- dev_err(dev, "failed to enable VDD regulator\n");
+ opp_table = dev_pm_opp_set_regulators(dev, &vdd, 1);
+ if (IS_ERR(opp_table)) {
+ ret = PTR_ERR(opp_table);
+ dev_err(dev, "failed to set regulators %d\n", ret);
return ret;
}
+ bus->opp_table = opp_table;
+
/*
* Get the devfreq-event devices to get the current utilization of
* buses. This raw data will be used in devfreq ondemand governor.
@@ -313,14 +232,11 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
if (of_property_read_u32(np, "exynos,saturation-ratio", &bus->ratio))
bus->ratio = DEFAULT_SATURATION_RATIO;
- if (of_property_read_u32(np, "exynos,voltage-tolerance",
- &bus->voltage_tolerance))
- bus->voltage_tolerance = DEFAULT_VOLTAGE_TOLERANCE;
-
return 0;
err_regulator:
- regulator_disable(bus->regulator);
+ dev_pm_opp_put_regulators(bus->opp_table);
+ bus->opp_table = NULL;
return ret;
}
@@ -471,7 +387,7 @@ static int exynos_bus_probe(struct platform_device *pdev)
goto out;
passive:
/* Initialize the struct profile and governor data for passive device */
- profile->target = exynos_bus_passive_target;
+ profile->target = exynos_bus_target;
profile->exit = exynos_bus_passive_exit;
/* Get the instance of parent devfreq device */
@@ -511,8 +427,10 @@ static int exynos_bus_probe(struct platform_device *pdev)
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
err_reg:
- if (!passive)
- regulator_disable(bus->regulator);
+ if (!passive) {
+ dev_pm_opp_put_regulators(bus->opp_table);
+ bus->opp_table = NULL;
+ }
return ret;
}
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v5 0/4] add coupled regulators for Exynos5422/5800
From: k.konieczny @ 2019-08-07 13:38 UTC (permalink / raw)
To: k.konieczny
Cc: Mark Rutland, Nishanth Menon, linux-samsung-soc, Rob Herring,
linux-arm-kernel, Bartlomiej Zolnierkiewicz, Stephen Boyd,
Viresh Kumar, linux-pm, linux-kernel, Krzysztof Kozlowski,
Chanwoo Choi, Kyungmin Park, Kukjin Kim, MyungJoo Ham, devicetree,
Marek Szyprowski
In-Reply-To: <CGME20190807133855eucas1p1cab425b791262e8dee1b17cbe8b1b3da@eucas1p1.samsung.com>
Hi,
The main purpose of this patch series is to add coupled regulators for
Exynos5422/5800 to keep constrain on voltage difference between vdd_arm
and vdd_int to be at most 300mV. In exynos-bus instead of using
regulator_set_voltage_tol() with default voltage tolerance it should be
used regulator_set_voltage_triplet() with volatege range, and this is
already present in opp/core.c code, so it can be reused. While at this,
move setting regulators into opp/core.
This patchset was tested on Odroid XU3.
The DTS coupled regulators patch depends on previous patches.
Changes:
v5:
- squashed last patch "remove exynos_bus_passive_target()" into second
- added Acked-by to patch "correct clock enable sequence"
v4:
- removed "opp: core: add regulators enable and disable" from patchset
as it was applied by Viresh Kumar and changed cover letter
- fix patch "devfreq: exynos-bus: correct clock enable sequence" to
correct order of enable/disable
- removed unrelated changes in "devfreq: exynos-bus: convert to use
dev_pm_opp_set_rate()"
- added new patch "devfreq: exynos-bus: remove exynos_bus_passive_target()"
as suggested by Chanwoo Choi
v3:
- added new exynos-bus patch to correct clock and regulator enabling
and disabling sequence as suggested by Chanwoo Choi
- corrected error path in enable and improved commit message in opp/core
- improve comment in devfreq/exynos-bus.c before devfreq_recommended_opp()
- change cover letter as there is new patch
- added note before Signed-off-by in 4th patch
v2:
- improve regulators enable/disable code in opp/core as suggested by
Viresh Kumar
- add new patch for remove unused dt-bindings as suggested by Krzysztof
Kozlowski
Kamil Konieczny (3):
devfreq: exynos-bus: correct clock enable sequence
devfreq: exynos-bus: convert to use dev_pm_opp_set_rate()
dt-bindings: devfreq: exynos-bus: remove unused property
Marek Szyprowski (1):
ARM: dts: exynos: add initial data for coupled regulators for
Exynos5422/5800
.../bindings/devfreq/exynos-bus.txt | 2 -
arch/arm/boot/dts/exynos5420.dtsi | 34 ++--
arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 4 +
arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +
arch/arm/boot/dts/exynos5800.dtsi | 32 ++--
drivers/devfreq/exynos-bus.c | 153 +++++-------------
6 files changed, 78 insertions(+), 151 deletions(-)
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ 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