Re: [PATCH v9 2/6] dt: bindings: add mt7621-clk device tree binding documentation

2021-03-05 Thread Chuanhong Guo
Hi Rob!

On Sat, Mar 6, 2021 at 6:48 AM Rob Herring  wrote:
>
> On Thu, Feb 18, 2021 at 08:07:05AM +0100, Sergio Paracuellos wrote:
> > Adds device tree binding documentation for clocks in the
> > MT7621 SOC.
> >
> > Signed-off-by: Sergio Paracuellos 
> > ---
> >  .../bindings/clock/mediatek,mt7621-clk.yaml   | 66 +++
> >  1 file changed, 66 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/clock/mediatek,mt7621-clk.yaml
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/clock/mediatek,mt7621-clk.yaml 
> > b/Documentation/devicetree/bindings/clock/mediatek,mt7621-clk.yaml
> > new file mode 100644
> > index ..842a0f2c9d40
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-clk.yaml
> > @@ -0,0 +1,66 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/mediatek,mt7621-clk.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MT7621 Clock Device Tree Bindings
> > +
> > +maintainers:
> > +  - Sergio Paracuellos 
> > +
> > +description: |
> > +  The MT7621 has a PLL controller from where the cpu clock is provided
> > +  as well as derived clocks for the bus and the peripherals. It also
> > +  can gate SoC device clocks.
> > +
> > +  Each clock is assigned an identifier and client nodes use this identifier
> > +  to specify the clock which they consume.
> > +
> > +  All these identifiers could be found in:
> > +  [1]: .
> > +
> > +properties:
> > +  compatible:
> > +const: mediatek,mt7621-clk
> > +
> > +  "#clock-cells":
> > +description:
> > +  The first cell indicates the clock number, see [1] for available
> > +  clocks.
> > +const: 1
> > +
> > +  ralink,sysctl:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description:
> > +  phandle of syscon used to control system registers
> > +
> > +  ralink,memctl:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description:
> > +  phandle of syscon used to control memory registers
>
> I assume one of these phandles are the main registers for the clocks?
> Make this a child node and drop that phandle.

On MT7621, CPU clock can be chosen from 3 sources: crystal clock,
a fixed 500MHz clock or a clock created by the memory controller.
sysctl contains a bootstrap register to determine crystal clock, a
clock mux for choosing between the 3 sources for CPU clock, and
a clock gate register for various peripherals. The ralink,memctl
phandle here is to read the cpu clock frequency from the memory
controller.
The original implementation hides this hardware detail to avoid
splitting the driver into three just for the CPU clock.
Is this approach okay and we can put it under sysctl node,
or this driver needs to be further splitted?

-- 
Regards,
Chuanhong Guo


Re: [PATCH] Add spi-nor driver for Realtek RTL838x/RTL839x switch SoCs

2020-12-20 Thread Chuanhong Guo
Hi!

On Sun, Dec 20, 2020 at 7:01 AM Bert Vermeulen  wrote:
>
> On 12/16/20 9:30 AM, tudor.amba...@microchip.com wrote:
> > On 12/15/20 11:46 PM, Bert Vermeulen wrote:
> >> This driver supports the spiflash core in all RTL838x/RTL839x SoCs,
> >> and likely some older models as well (RTL8196C).
> >>
> > Can we use SPIMEM and move this under drivers/spi/ instead?
>
> I wasn't aware spimem was the thing to use for new drivers. I will rewrite
> the driver to that API.

Are there any limitations preventing this from being implemented as a
generic SPI controller?
spi-nor and spi-mem are designed for controllers which can only perform
spi-mem/spi-nor specific transfers. I can't find such limitations from
your current driver code.

BTW I found a SPI controller driver for RTL8196C here: [0]
It seems pretty similar to the controller you are working on.

[0]: 
https://github.com/hackpascal/lede-rtl8196c/blob/realtek/target/linux/realtek/files/drivers/spi/spi-realtek.c

-- 
Regards,
Chuanhong Guo


Re: [PATCH] Add spi-nor driver for Realtek RTL838x/RTL839x switch SoCs

2020-12-16 Thread Chuanhong Guo
Hi!

On Wed, Dec 16, 2020 at 4:30 PM  wrote:
>
> On 12/15/20 11:46 PM, Bert Vermeulen wrote:
> > This driver supports the spiflash core in all RTL838x/RTL839x SoCs,
> > and likely some older models as well (RTL8196C).
> >
> Can we use SPIMEM and move this under drivers/spi/ instead?
>
> Cheers,
> ta

Just took a brief look at the code, and here's my current understanding
of this controller:
1. CS is controlled separately with SFCSR_CSB* bits
2. To write 1-4 bytes, set SFCSR_LEN* and write to SFDR
2. To read 1-4 bytes, set SFCSR_LEN* and read SFDR

If that's true, this is a generic half-duplex spi controller, and the driver
should register a spi_controller with set_cs and transfer_one
implemented.

-- 
Regards,
Chuanhong Guo


Re: [PATCH v3 3/5] clk: ralink: add clock driver for mt7621 SoC

2020-11-19 Thread Chuanhong Guo
Hi!

On Fri, Nov 13, 2020 at 11:46 PM Sergio Paracuellos
 wrote:
> [...]
> diff --git a/drivers/clk/ralink/Makefile b/drivers/clk/ralink/Makefile
> new file mode 100644
> index ..cf6f9216379d
> --- /dev/null
> +++ b/drivers/clk/ralink/Makefile

Why ralink? The clock design of mt7621 doesn't seem
to be part of ralink legacy stuff, and ralink is already
acquired by mediatek anyway.
I think it should be put in drivers/clk/mediatek instead.

-- 
Regards,
Chuanhong Guo


Re: [PATCH 0/7] MIPS: ralink: add CPU clock detection and clock gate driver for MT7621

2020-11-12 Thread Chuanhong Guo
On Thu, Nov 12, 2020 at 1:23 PM Sergio Paracuellos
 wrote:
>
> To avoid weird behaviour because of some drivers are
> not using properly clocks we have the CLK_IGNORED_UNUSED, which as you
> can see is currently being used in my code. Using that all seems to
> work as expected as it is now.

The whole point of having a clock gate driver is to gate unused
clocks to save (maybe a tiny bit of) power. It's other peripheral
drivers' fault that it doesn't enable clocks properly and we shouldn't
just work-around the problem in the clock driver by disallowing auto
clock gating.

-- 
Regards,
Chuanhong Guo


Re: [PATCH 0/7] MIPS: ralink: add CPU clock detection and clock gate driver for MT7621

2020-11-11 Thread Chuanhong Guo
On Thu, Nov 12, 2020 at 9:26 AM Chuanhong Guo  wrote:
>
> I've already said in previous threads that clock assignment in
> current linux kernel is not trustworthy.
> I've got the clock plan for mt7621 now. (Can't share it, sorry.)
> Most of your clock assumptions above are incorrect.
> I've made a clock driver with gate support a few months ago.[0]
> but I don't have much time to really finish it.
> Maybe you could rework your clock gate driver based on it.
>
> [0] 
> https://github.com/981213/linux/commit/2eca1f045e4c3db18c941135464c0d7422ad8133

hsdma/eth/pio clocks are still missing in mediatek doc and
I just made them up in the driver. Correct clock frequency for
them aren't really important for them to work though.
And another part I didn't finish is checking clock support for
every drivers mt7621 used. Many drivers don't explicitly
enable the clock and may be problematic when kernel
gates unused clocks.

-- 
Regards,
Chuanhong Guo


Re: [PATCH 0/7] MIPS: ralink: add CPU clock detection and clock gate driver for MT7621

2020-11-11 Thread Chuanhong Guo
Hi!

On Thu, Nov 12, 2020 at 12:30 AM Sergio Paracuellos
 wrote:
>
> This patchset ports CPU clock detection for MT7621 from OpenWrt
> and adds a complete clock plan for the mt7621 SOC.
>
> The documentation for this SOC only talks about two registers
> regarding to the clocks:
> * SYSC_REG_CPLL_CLKCFG0 - provides some information about boostrapped
> refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
> * SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
> all or some ip cores.
>
> No documentation about a probably existant set of dividers for each ip
> core is included in the datasheets. So we cannot make anything better,
> AFAICT.
>
> Looking into driver code, there is another frequency which is used in
> some drivers (uart, sd...) which for any reason is always hardcoded to
> 50 MHz. Taking this into account this patchset provides three main fixed
> clocks to the SOC in 'mt7621-pll' which are:
>   - "cpu": with detected frequency (900 MHz in my board).
>   - "ahb": cpu / 4 = 225 Mhz.
>   - "apb": 50 Mhz.
>
> PLL controller cannot be manipulatedbecause there is no info about
> how to do it. Because of this, there is nothing related with registers
> in the included binding.
>
> It also provides a clock gate driver 'mt7621-clk' as a platform driver
> to allow to enable and disable some clocks in the different ip cores.
> The parent clocks for this clock gates have also set taking into account
> existant device tree and driver code resulting in the followings:
>   - "hsdma": "ahb"
>   - "fe": "ahb"
>   - "sp_divtx": "ahb"
>   - "timer": "cpu"
>   - "int": "cpu"
>   - "mc": "ahb"
>   - "pcm": "ahb"
>   - "pio": "ahb"
>   - "gdma": "ahb"
>   - "nand": "ahb"
>   - "i2c": "ahb"
>   - "i2s": "ahb"
>   - "spi": "ahb"
>   - "uart1": "apb"
>   - "uart2": "apb"
>   - "uart3": "apb"
>   - "eth": "ahb"
>   - "pcie0": "ahb"
>   - "pcie1": "ahb"
>   - "pcie2": "ahb"
>   - "crypto": "ahb"
>   - "shxc": "ahb"
>
> There was a previous attempt of doing this here[0] but the author
> did not wanted to make assumptions of a clock plan for the platform.

I've already said in previous threads that clock assignment in
current linux kernel is not trustworthy.
I've got the clock plan for mt7621 now. (Can't share it, sorry.)
Most of your clock assumptions above are incorrect.
I've made a clock driver with gate support a few months ago.[0]
but I don't have much time to really finish it.
Maybe you could rework your clock gate driver based on it.

[0] 
https://github.com/981213/linux/commit/2eca1f045e4c3db18c941135464c0d7422ad8133
-- 
Regards,
Chuanhong Guo


[PATCH] MIPS: zboot: put appended dtb into a section

2020-10-26 Thread Chuanhong Guo
This will make a separated section for dtb appear in ELF, and we can
then use objcopy to patch a dtb into vmlinuz when RAW_APPENDED_DTB
is set in kernel config.

command to patch a dtb:
objcopy --set-section-flags=.appended_dtb=alloc,contents \
--update-section=.appended_dtb=.dtb vmlinuz

Signed-off-by: Chuanhong Guo 
---
Note:
This should supersede this patch on linux-mips:
[2/2] mips: boot compressed: add support for vlinuz ELF DTB [0]

[0] 
https://patchwork.kernel.org/project/linux-mips/patch/20201015201100.4130-2-...@johnthomson.fastmail.com.au/
 
 arch/mips/boot/compressed/ld.script | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/mips/boot/compressed/ld.script 
b/arch/mips/boot/compressed/ld.script
index 2ed08fbef8e7..0ebb667274d6 100644
--- a/arch/mips/boot/compressed/ld.script
+++ b/arch/mips/boot/compressed/ld.script
@@ -31,9 +31,12 @@ SECTIONS
CONSTRUCTORS
. = ALIGN(16);
}
-   __appended_dtb = .;
-   /* leave space for appended DTB */
-   . += 0x10;
+
+   .appended_dtb : {
+   __appended_dtb = .;
+   /* leave space for appended DTB */
+   . += 0x10;
+   }
 
_edata = .;
/* End of data section */
-- 
2.26.2



[PATCH] mips: ralink: mt7621: add zboot debug console

2020-10-14 Thread Chuanhong Guo
uartlite0 at 0x1e000c00 is a 16550 compatible uart controller. It's
usually used for debug console and is already configured by u-boot.
Add ZBOOT_UART16550 and related definitions in uart-16550.c for zboot
debug output.

Signed-off-by: Chuanhong Guo 
---
 arch/mips/boot/compressed/uart-16550.c | 6 ++
 arch/mips/ralink/Kconfig   | 1 +
 2 files changed, 7 insertions(+)

diff --git a/arch/mips/boot/compressed/uart-16550.c 
b/arch/mips/boot/compressed/uart-16550.c
index aee8d7b8f091..7122df28967a 100644
--- a/arch/mips/boot/compressed/uart-16550.c
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -35,6 +35,12 @@
 #define IOTYPE unsigned int
 #endif
 
+#ifdef CONFIG_SOC_MT7621
+#define UART0_BASE  0x1e000c00
+#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
+#define IOTYPE unsigned int
+#endif
+
 #ifndef IOTYPE
 #define IOTYPE char
 #endif
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index c10d8b233ab1..4c3c6ef330e3 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -52,6 +52,7 @@ choice
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_MIPS_CPS
select SYS_SUPPORTS_HIGHMEM
+   select SYS_SUPPORTS_ZBOOT_UART16550
select MIPS_GIC
select COMMON_CLK
select CLKSRC_MIPS_GIC
-- 
2.26.2



[PATCH] mips: ralink: enable zboot support

2020-10-12 Thread Chuanhong Guo
Some of these ralink devices come with an ancient u-boot which can't
extract LZMA properly when image gets too big.
Enable zboot support to get a self-extracting kernel instead of relying
on broken u-boot support.

Signed-off-by: Chuanhong Guo 
---
 arch/mips/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f52fa211a4cf..534ecff2e2c5 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -618,6 +618,7 @@ config RALINK
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MIPS16
+   select SYS_SUPPORTS_ZBOOT
select SYS_HAS_EARLY_PRINTK
select CLKDEV_LOOKUP
select ARCH_HAS_RESET_CONTROLLER
-- 
2.26.2



Re: [PATCH v3 5/6] spi: spi-mtk-nor: support 36bit dma addressing

2020-09-25 Thread Chuanhong Guo
Hi!

On Fri, Sep 25, 2020 at 2:56 PM Ikjoon Jang  wrote:
>
> This patch enables 36bit dma address support to spi-mtk-nor.
> Currently this is enabled only for mt8192-nor.
>
> Signed-off-by: Ikjoon Jang 
> ---
>
> (no changes since v1)
>
>  drivers/spi/spi-mtk-nor.c | 18 +-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
> index 8dbafee7f431..35205635ed42 100644
> --- a/drivers/spi/spi-mtk-nor.c
> +++ b/drivers/spi/spi-mtk-nor.c
> @@ -78,6 +78,8 @@
>  #define MTK_NOR_REG_DMA_FADR   0x71c
>  #define MTK_NOR_REG_DMA_DADR   0x720
>  #define MTK_NOR_REG_DMA_END_DADR   0x724
> +#define MTK_NOR_REG_DMA_DADR_HB0x738
> +#define MTK_NOR_REG_DMA_END_DADR_HB0x73c
>
>  /* maximum bytes of TX in PRG mode */
>  #define MTK_NOR_PRG_MAX_SIZE   6
> @@ -106,6 +108,7 @@ struct mtk_nor {
> unsigned int spi_freq;
> bool wbuf_en;
> bool has_irq;
> +   bool high_dma;
> struct completion op_done;
>  };
>
> @@ -305,6 +308,11 @@ static int mtk_nor_dma_exec(struct mtk_nor *sp, u32 
> from, unsigned int length,
> writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR);
> writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR);
>
> +   if (sp->high_dma) {
> +   writel(dma_addr >> 32, sp->base + MTK_NOR_REG_DMA_DADR_HB);
> +   writel((dma_addr + length) >> 32, sp->base + 
> MTK_NOR_REG_DMA_END_DADR_HB);
> +   }

I remembered kbuild test robot reported a warning on this on 32-bit platforms
in your v1. [0]
I don't know what's the fix for this though :(

[0] https://marc.info/?l=linux-spi=159982425706940=2
-- 
Regards,
Chuanhong Guo


Re: [PATCH v3 4/6] spi: spi-mtk-nor: use dma_alloc_coherent() for bounce buffer

2020-09-25 Thread Chuanhong Guo
Hi!

On Fri, Sep 25, 2020 at 2:56 PM Ikjoon Jang  wrote:
>
> Use dma_alloc_coherent() for bounce buffer instead of kmalloc() to
> make sure the bounce buffer to be allocated within its DMAable range.

I think the introduction of need_bounce can be in its own commit or
at least mentioned here.

>
> Signed-off-by: Ikjoon Jang 
>
> ---
>
> (no changes since v1)

 There have been a lot of changes since v2 :)

Reviewed-by: Chuanhong Guo 
-- 
Regards,
Chuanhong Guo


Re: [PATCH v3 3/6] spi: spi-mtk-nor: support 7 bytes transfer of generic spi

2020-09-25 Thread Chuanhong Guo
HI!
One more comment:
On Fri, Sep 25, 2020 at 2:55 PM Ikjoon Jang  wrote:
> +static bool mtk_nor_check_prg(const struct spi_mem_op *op)
> +{
> +   size_t len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
> +
> +   if (len > MTK_NOR_PRG_MAX_SIZE)
> +   return false;
> +
> +   if (!op->data.nbytes)
> +   return true;
> +
> +   if (op->data.dir == SPI_MEM_DATA_OUT)
> +   return ((len + op->data.nbytes) <= MTK_NOR_PRG_MAX_SIZE);
> +   else if (op->data.dir == SPI_MEM_DATA_IN)
> +   return ((len + op->data.nbytes) <= MTK_NOR_PRG_MAX_CYCLES);

You need to consider the existence of adjust_op_size in supports_op as well.
This mtk_nor_check_prg still rejects SFDP reading command from spi-nor
driver altogether.

-- 
Regards,
Chuanhong Guo


Re: [PATCH v3 3/6] spi: spi-mtk-nor: support 7 bytes transfer of generic spi

2020-09-25 Thread Chuanhong Guo
tells caller to abort this transfer completely.
A fallback only happens when exec_op returns -ENOTSUPP.
This comment is incorrect. I'd put this buswidth checking in mtk_nor_check_prg
instead because mtk_nor_check_prg is checking whether an op is supported
by prg mode, thus it should reject ops with buswidth > 1.

>
> -   return true;
> +   return mtk_nor_check_prg(op);
>  }
>
>  static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op 
> *op)
> @@ -459,22 +490,36 @@ static int mtk_nor_transfer_one_message(struct 
> spi_controller *master,
> int stat = 0;
> int reg_offset = MTK_NOR_REG_PRGDATA_MAX;
> void __iomem *reg;
> -   const u8 *txbuf;
> -   u8 *rxbuf;
> -   int i;
> +   int i, tx_len = 0, rx_len = 0;
>
> list_for_each_entry(t, >transfers, transfer_list) {
> -   txbuf = t->tx_buf;
> -   for (i = 0; i < t->len; i++, reg_offset--) {
> +   const u8 *txbuf = t->tx_buf;
> +
> +   if (!txbuf) {
> +   rx_len += t->len;
> +   continue;
> +   }
> +
> +   if (rx_len) {
> +   stat = -EPROTO;
> +   goto msg_done;
> +   }

NACK. you are unnecessarily rejecting possible transfers.

> +
> +   for (i = 0; i < t->len && reg_offset >= 0; i++, reg_offset--) 
> {
> reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
> -   if (txbuf)
> -   writeb(txbuf[i], reg);
> -   else
> -   writeb(0, reg);
> +   writeb(txbuf[i], reg);
> +   tx_len++;

According to SPI standard, during a rx transfer, tx should be kept low.
These PROGDATA registers doesn't clear itself so it'll keep sending
data from last transfer, which violates this rule. That's
why the original code writes 0 to PRGDATA for rx bytes.

> }
> -   trx_len += t->len;
> }
>
> +   while (reg_offset >= 0) {
> +   writeb(0, sp->base + MTK_NOR_REG_PRGDATA(reg_offset));
> +   reg_offset--;
> +   }
> +
> +   rx_len = min_t(unsigned long, MTK_NOR_PRG_MAX_CYCLES - tx_len, 
> rx_len);
> +   trx_len = tx_len + rx_len;
> +
> writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT);
>
> stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM,
> @@ -482,13 +527,18 @@ static int mtk_nor_transfer_one_message(struct 
> spi_controller *master,
> if (stat < 0)
> goto msg_done;
>
> -   reg_offset = trx_len - 1;
> -   list_for_each_entry(t, >transfers, transfer_list) {
> -   rxbuf = t->rx_buf;
> -   for (i = 0; i < t->len; i++, reg_offset--) {
> -   reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset);
> -   if (rxbuf)
> +   if (rx_len > 0) {
> +   reg_offset = rx_len - 1;
> +   list_for_each_entry(t, >transfers, transfer_list) {
> +   u8 *rxbuf = t->rx_buf;
> +
> +   if (!rxbuf)
> +   continue;
> +
> +   for (i = 0; i < t->len && reg_offset >= 0; i++, 
> reg_offset--) {
> +   reg = sp->base + 
> MTK_NOR_REG_SHIFT(reg_offset);
> rxbuf[i] = readb(reg);
> +   }

I think this is replacing original code with some equivalent ones, which
seems unnecessary.

> }
> }
>
-- 
Regards,
Chuanhong Guo


[PATCH 2/3] spi: spi-mtk-nor: add helper for checking prg mode ops

2020-09-24 Thread Chuanhong Guo
op checking/resizing logic for the newly added mtk_nor_spi_mem_prg is
more complicated. Add two helper functions for them:
mtk_nor_match_prg: check whether an op is supported by prg mode.
mtk_nor_adj_prg_size: adjust data size for mtk_nor_spi_mem_prg.

mtk_nor_match_prg isn't called yet because supports_op is currently
broken. It'll be used in the next fix commit.

Signed-off-by: Chuanhong Guo 
---
 drivers/spi/spi-mtk-nor.c | 76 +++
 1 file changed, 69 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index a0087a5e869b9..4bbf38ef5b4b1 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -168,10 +168,76 @@ static bool mtk_nor_match_read(const struct spi_mem_op 
*op)
return false;
 }
 
-static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+static bool mtk_nor_match_prg(const struct spi_mem_op *op)
 {
-   size_t len;
+   int tx_len, rx_len, prg_len, prg_left;
+
+   // prg mode is spi-only.
+   if ((op->cmd.buswidth > 1) || (op->addr.buswidth > 1) ||
+   (op->dummy.buswidth > 1) || (op->data.buswidth > 1))
+   return false;
+
+   tx_len = op->cmd.nbytes + op->addr.nbytes;
+
+   if (op->data.dir == SPI_MEM_DATA_OUT) {
+   // count dummy bytes only if we need to write data after it
+   tx_len += op->dummy.nbytes;
+
+   // leave at least one byte for data
+   if (tx_len > MTK_NOR_REG_PRGDATA_MAX)
+   return false;
+
+   // if there's no addr, meaning adjust_op_size is impossible,
+   // check data length as well.
+   if ((!op->addr.nbytes) &&
+   (tx_len + op->data.nbytes > MTK_NOR_REG_PRGDATA_MAX + 1))
+   return false;
+   } else if (op->data.dir == SPI_MEM_DATA_IN) {
+   if (tx_len > MTK_NOR_REG_PRGDATA_MAX + 1)
+   return false;
+
+   rx_len = op->data.nbytes;
+   prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes;
+   if (prg_left > MTK_NOR_REG_SHIFT_MAX + 1)
+   prg_left = MTK_NOR_REG_SHIFT_MAX + 1;
+   if (rx_len > prg_left) {
+   if (!op->addr.nbytes)
+   return false;
+   rx_len = prg_left;
+   }
+
+   prg_len = tx_len + op->dummy.nbytes + rx_len;
+   if (prg_len > MTK_NOR_PRG_CNT_MAX / 8)
+   return false;
+   } else {
+   prg_len = tx_len + op->dummy.nbytes;
+   if (prg_len > MTK_NOR_PRG_CNT_MAX / 8)
+   return false;
+   }
+   return true;
+}
 
+static void mtk_nor_adj_prg_size(struct spi_mem_op *op)
+{
+   int tx_len, tx_left, prg_left;
+
+   tx_len = op->cmd.nbytes + op->addr.nbytes;
+   if (op->data.dir == SPI_MEM_DATA_OUT) {
+   tx_len += op->dummy.nbytes;
+   tx_left = MTK_NOR_REG_PRGDATA_MAX + 1 - tx_len;
+   if (op->data.nbytes > tx_left)
+   op->data.nbytes = tx_left;
+   } else if (op->data.dir == SPI_MEM_DATA_IN) {
+   prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes;
+   if (prg_left > MTK_NOR_REG_SHIFT_MAX + 1)
+   prg_left = MTK_NOR_REG_SHIFT_MAX + 1;
+   if (op->data.nbytes > prg_left)
+   op->data.nbytes = prg_left;
+   }
+}
+
+static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
if (!op->data.nbytes)
return 0;
 
@@ -200,11 +266,7 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, 
struct spi_mem_op *op)
}
}
 
-   len = MTK_NOR_PRG_MAX_SIZE - op->cmd.nbytes - op->addr.nbytes -
- op->dummy.nbytes;
-   if (op->data.nbytes > len)
-   op->data.nbytes = len;
-
+   mtk_nor_adj_prg_size(op);
return 0;
 }
 
-- 
2.26.2



[PATCH 3/3] spi: spi-mtk-nor: fix op checks in supports_op

2020-09-24 Thread Chuanhong Guo
commit a59b2c7c56bf7 ("spi: spi-mtk-nor: support standard spi properties")
tries to inverse the logic of supports_op when adding
spi_mem_default_supports_op check, but it didn't get it done properly.
There are two regressions introduced by this commit:
1. reading ops supported by program mode is rejected.
2. all ops with special controller routines are incorrectly further
   checked against program mode.

This commits inverses the logic back:
1. check spi_mem_default_supports_op and reject unsupported ops first.
2. return true for ops with special controller routines.
3. check the left ops against controller program mode.

Fixes: a59b2c7c56bf7 ("spi: spi-mtk-nor: support standard spi properties")
Signed-off-by: Chuanhong Guo 
---
 drivers/spi/spi-mtk-nor.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 4bbf38ef5b4b1..ea39736de2918 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -273,7 +273,8 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, 
struct spi_mem_op *op)
 static bool mtk_nor_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
 {
-   size_t len;
+   if (!spi_mem_default_supports_op(mem, op))
+   return false;
 
if (op->cmd.buswidth != 1)
return false;
@@ -281,25 +282,21 @@ static bool mtk_nor_supports_op(struct spi_mem *mem,
if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
switch(op->data.dir) {
case SPI_MEM_DATA_IN:
-   if (!mtk_nor_match_read(op))
-   return false;
+   if (mtk_nor_match_read(op))
+   return true;
break;
case SPI_MEM_DATA_OUT:
-   if ((op->addr.buswidth != 1) ||
-   (op->dummy.nbytes != 0) ||
-   (op->data.buswidth != 1))
-   return false;
+   if ((op->addr.buswidth == 1) &&
+   (op->dummy.nbytes == 0) &&
+   (op->data.buswidth == 1))
+   return true;
break;
default:
break;
}
}
-   len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
-   if ((len > MTK_NOR_PRG_MAX_SIZE) ||
-   ((op->data.nbytes) && (len == MTK_NOR_PRG_MAX_SIZE)))
-   return false;
 
-   return spi_mem_default_supports_op(mem, op);
+   return mtk_nor_match_prg(op);
 }
 
 static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op)
-- 
2.26.2



[PATCH 1/3] spi: spi-mtk-nor: make use of full capability of prg mode

2020-09-24 Thread Chuanhong Guo
"program" mode on this controller can trigger up to 56 bits of data
shifting. During the operation, data in PRGDATA[0-5] will be
shifted out from MOSI, and data from MISO will be continuously filling
SHREG[0-9].
Currently this mode is used to implement transfer_one_message for 6-byte
full-duplex transfer, but it can execute a transfer for up-to 7 bytes
as long as the last byte is read only.
transfer_one_message is expected to perform full-duplex transfer,
instead of transfer with specific format. mtk_nor_spi_mem_prg is
added here to use this extra byte.

Newer version of this controller can trigger longer data shifting with
shift bytes more than PRGDATA_MAX + SHREG_MAX. This patch is implemented
with that in mind and it checks against both SHREG_MAX and PRG_CNT_MAX
for future support of new controllers.

Signed-off-by: Chuanhong Guo 
---
There are two calls of mtk_nor_spi_mem_prg in mtk_nor_exec_op,
which doesn't look great. But I'd prefer keeping it this way
to minimize change of mtk_nor_exec_op.
I'll follow up with a cleanup patchset after this one gets
merged.

 drivers/spi/spi-mtk-nor.c | 82 ++-
 1 file changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 62f5ff2779884..a0087a5e869b9 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -27,6 +27,7 @@
 #define MTK_NOR_CMD_MASK   GENMASK(5, 0)
 
 #define MTK_NOR_REG_PRG_CNT0x04
+#define MTK_NOR_PRG_CNT_MAX56
 #define MTK_NOR_REG_RDATA  0x0c
 
 #define MTK_NOR_REG_RADR0  0x10
@@ -404,6 +405,83 @@ static int mtk_nor_pp_unbuffered(struct mtk_nor *sp,
return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE);
 }
 
+static int mtk_nor_spi_mem_prg(struct mtk_nor *sp, const struct spi_mem_op *op)
+{
+   int rx_len = 0;
+   int reg_offset = MTK_NOR_REG_PRGDATA_MAX;
+   int tx_len, prg_len;
+   int i, ret;
+   void __iomem *reg;
+   u8 bufbyte;
+
+   tx_len = op->cmd.nbytes + op->addr.nbytes;
+
+   // count dummy bytes only if we need to write data after it
+   if (op->data.dir == SPI_MEM_DATA_OUT)
+   tx_len += op->dummy.nbytes + op->data.nbytes;
+   else if (op->data.dir == SPI_MEM_DATA_IN)
+   rx_len = op->data.nbytes;
+
+   prg_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes +
+ op->data.nbytes;
+
+   // an invalid op may reach here if the caller calls exec_op without
+   // adjust_op_size. return -EINVAL instead of -ENOTSUPP so that
+   // spi-mem won't try this op again with generic spi transfers.
+   if ((tx_len > MTK_NOR_REG_PRGDATA_MAX + 1) ||
+   (rx_len > MTK_NOR_REG_SHIFT_MAX + 1) ||
+   (prg_len > MTK_NOR_PRG_CNT_MAX / 8))
+   return -EINVAL;
+
+   // fill tx data
+   for (i = op->cmd.nbytes; i > 0; i--, reg_offset--) {
+   reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
+   bufbyte = (op->cmd.opcode >> ((i - 1) * BITS_PER_BYTE)) & 0xff;
+   writeb(bufbyte, reg);
+   }
+
+   for (i = op->addr.nbytes; i > 0; i--, reg_offset--) {
+   reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
+   bufbyte = (op->addr.val >> ((i - 1) * BITS_PER_BYTE)) & 0xff;
+   writeb(bufbyte, reg);
+   }
+
+   if (op->data.dir == SPI_MEM_DATA_OUT) {
+   for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) {
+   reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
+   writeb(0, reg);
+   }
+
+   for (i = 0; i < op->data.nbytes; i++, reg_offset--) {
+   reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
+   writeb(((const u8 *)(op->data.buf.out))[i], reg);
+   }
+   }
+
+   for (; reg_offset >= 0; reg_offset--) {
+   reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset);
+   writeb(0, reg);
+   }
+
+   // trigger op
+   writel(prg_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT);
+   ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM,
+  prg_len * BITS_PER_BYTE);
+   if (ret)
+   return ret;
+
+   // fetch read data
+   reg_offset = 0;
+   if (op->data.dir == SPI_MEM_DATA_IN) {
+   for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) {
+   reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset);
+   ((u8 *)(op->data.buf.in))[i] = readb(reg);
+   }
+   }
+
+   return 0;
+}
+
 static int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
struct mtk_nor *sp = spi_controller_get_devdata(mem->

[PATCH 0/3] spi: spi-mtk-nor: make use of full capability of program mode

2020-09-24 Thread Chuanhong Guo
"program" mode on this controller can trigger up to 56 bits of data
shifting. During the operation, data in PRGDATA[0-5] will be
shifted out from MOSI, and data from MISO will be continuously filling
SHREG[0-9].
Currently this mode is used to implement transfer_one_message for 6-byte
full-duplex transfer, but it can execute a transfer for up-to 7 bytes
as long as the last byte is read only.
transfer_one_message is expected to perform full-duplex transfer,
instead of transfer with specific format. mtk_nor_spi_mem_prg is
added here to use this extra byte.

Newer version of this controller can trigger longer data shifting with
shift bytes more than PRGDATA_MAX + SHREG_MAX. This patch is implemented
with that in mind and it checks against both SHREG_MAX and PRG_CNT_MAX
for future support of new controllers.

Patch 3/3 is a fix for:
commit a59b2c7c56bf7 ("spi: spi-mtk-nor: support standard spi properties")
which breaks supports_op logic. But it can't be separated as it depends
on patch 2/3. Fortuantely the broken commit isn't in stable yet.

Chuanhong Guo (3):
  spi: spi-mtk-nor: make use of full capability of prg mode
  spi: spi-mtk-nor: add helper for checking prg mode ops
  spi: spi-mtk-nor: fix op checks in supports_op

 drivers/spi/spi-mtk-nor.c | 179 +-
 1 file changed, 158 insertions(+), 21 deletions(-)

-- 
2.26.2



[PATCH] mt76: mt7615: retry if mt7615_mcu_init returns -EAGAIN

2020-09-23 Thread Chuanhong Guo
mt7615_load_patch in mt7615/mcu.c sometimes fails with:
mt7622-wmac 1800.wmac: Failed to get patch semaphore
and returns -EAGAIN. But this error is returned all the way up to
mt7615_init_work with no actual retrial performed, leaving a
broken wireless phy.
Wait a bit and retry for up to 10 times before giving up.

Signed-off-by: Chuanhong Guo 
---
On my mt7622 board mt7615_load_patch always fails the first time
and it then succeeded on the first retry added by this patch.
"10 times" is an arbitarily picked value and it'll still leave a
broken phy behind if all 10 retries failed. I don't know if that's
okay. Suggestions are welcome!

 drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
index 7224a00782115..2272f6bcaafe7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
@@ -16,8 +16,15 @@ static void mt7615_init_work(struct work_struct *work)
 {
struct mt7615_dev *dev = container_of(work, struct mt7615_dev,
  mcu_work);
+   int i, ret;
 
-   if (mt7615_mcu_init(dev))
+   ret = mt7615_mcu_init(dev);
+   for (i = 0; (ret == -EAGAIN) && (i < 10); i++) {
+   msleep(200);
+   ret = mt7615_mcu_init(dev);
+   }
+
+   if (ret)
return;
 
mt7615_mcu_set_eeprom(dev);
-- 
2.26.2



[PATCH] pinctrl: mediatek: mt7622: add antsel pins/groups

2020-09-22 Thread Chuanhong Guo
These pins are named ANTSEL[0~29] in datasheet and are used by wmac for
various functions.

Signed-off-by: Chuanhong Guo 
---
 drivers/pinctrl/mediatek/pinctrl-mt7622.c | 103 ++
 1 file changed, 103 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c 
b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
index ce4a8a0cc19cb..38c5e166fd0f6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
@@ -263,6 +263,68 @@ static const struct mtk_pin_desc mt7622_pins[] = {
  * hardware probably has multiple combinations of these pinouts.
  */
 
+/* ANTSEL */
+static int mt7622_antsel0_pins[] = { 91, };
+static int mt7622_antsel0_funcs[] = { 5, };
+static int mt7622_antsel1_pins[] = { 92, };
+static int mt7622_antsel1_funcs[] = { 5, };
+static int mt7622_antsel2_pins[] = { 93, };
+static int mt7622_antsel2_funcs[] = { 5, };
+static int mt7622_antsel3_pins[] = { 94, };
+static int mt7622_antsel3_funcs[] = { 5, };
+static int mt7622_antsel4_pins[] = { 95, };
+static int mt7622_antsel4_funcs[] = { 5, };
+static int mt7622_antsel5_pins[] = { 96, };
+static int mt7622_antsel5_funcs[] = { 5, };
+static int mt7622_antsel6_pins[] = { 97, };
+static int mt7622_antsel6_funcs[] = { 5, };
+static int mt7622_antsel7_pins[] = { 98, };
+static int mt7622_antsel7_funcs[] = { 5, };
+static int mt7622_antsel8_pins[] = { 99, };
+static int mt7622_antsel8_funcs[] = { 5, };
+static int mt7622_antsel9_pins[] = { 100, };
+static int mt7622_antsel9_funcs[] = { 5, };
+static int mt7622_antsel10_pins[] = { 101, };
+static int mt7622_antsel10_funcs[] = { 5, };
+static int mt7622_antsel11_pins[] = { 102, };
+static int mt7622_antsel11_funcs[] = { 5, };
+static int mt7622_antsel12_pins[] = { 73, };
+static int mt7622_antsel12_funcs[] = { 5, };
+static int mt7622_antsel13_pins[] = { 74, };
+static int mt7622_antsel13_funcs[] = { 5, };
+static int mt7622_antsel14_pins[] = { 75, };
+static int mt7622_antsel14_funcs[] = { 5, };
+static int mt7622_antsel15_pins[] = { 76, };
+static int mt7622_antsel15_funcs[] = { 5, };
+static int mt7622_antsel16_pins[] = { 77, };
+static int mt7622_antsel16_funcs[] = { 5, };
+static int mt7622_antsel17_pins[] = { 22, };
+static int mt7622_antsel17_funcs[] = { 5, };
+static int mt7622_antsel18_pins[] = { 79, };
+static int mt7622_antsel18_funcs[] = { 5, };
+static int mt7622_antsel19_pins[] = { 80, };
+static int mt7622_antsel19_funcs[] = { 5, };
+static int mt7622_antsel20_pins[] = { 81, };
+static int mt7622_antsel20_funcs[] = { 5, };
+static int mt7622_antsel21_pins[] = { 82, };
+static int mt7622_antsel21_funcs[] = { 5, };
+static int mt7622_antsel22_pins[] = { 14, };
+static int mt7622_antsel22_funcs[] = { 5, };
+static int mt7622_antsel23_pins[] = { 15, };
+static int mt7622_antsel23_funcs[] = { 5, };
+static int mt7622_antsel24_pins[] = { 16, };
+static int mt7622_antsel24_funcs[] = { 5, };
+static int mt7622_antsel25_pins[] = { 17, };
+static int mt7622_antsel25_funcs[] = { 5, };
+static int mt7622_antsel26_pins[] = { 18, };
+static int mt7622_antsel26_funcs[] = { 5, };
+static int mt7622_antsel27_pins[] = { 19, };
+static int mt7622_antsel27_funcs[] = { 5, };
+static int mt7622_antsel28_pins[] = { 20, };
+static int mt7622_antsel28_funcs[] = { 5, };
+static int mt7622_antsel29_pins[] = { 21, };
+static int mt7622_antsel29_funcs[] = { 5, };
+
 /* EMMC */
 static int mt7622_emmc_pins[] = { 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, };
 static int mt7622_emmc_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
@@ -543,6 +605,36 @@ static int mt7622_wled_pins[] = { 85, };
 static int mt7622_wled_funcs[] = { 0, };
 
 static const struct group_desc mt7622_groups[] = {
+   PINCTRL_PIN_GROUP("antsel0", mt7622_antsel0),
+   PINCTRL_PIN_GROUP("antsel1", mt7622_antsel1),
+   PINCTRL_PIN_GROUP("antsel2", mt7622_antsel2),
+   PINCTRL_PIN_GROUP("antsel3", mt7622_antsel3),
+   PINCTRL_PIN_GROUP("antsel4", mt7622_antsel4),
+   PINCTRL_PIN_GROUP("antsel5", mt7622_antsel5),
+   PINCTRL_PIN_GROUP("antsel6", mt7622_antsel6),
+   PINCTRL_PIN_GROUP("antsel7", mt7622_antsel7),
+   PINCTRL_PIN_GROUP("antsel8", mt7622_antsel8),
+   PINCTRL_PIN_GROUP("antsel9", mt7622_antsel9),
+   PINCTRL_PIN_GROUP("antsel10", mt7622_antsel10),
+   PINCTRL_PIN_GROUP("antsel11", mt7622_antsel11),
+   PINCTRL_PIN_GROUP("antsel12", mt7622_antsel12),
+   PINCTRL_PIN_GROUP("antsel13", mt7622_antsel13),
+   PINCTRL_PIN_GROUP("antsel14", mt7622_antsel14),
+   PINCTRL_PIN_GROUP("antsel15", mt7622_antsel15),
+   PINCTRL_PIN_GROUP("antsel16", mt7622_antsel16),
+   PINCTRL_PIN_GROUP("antsel17", mt7622_antsel17),
+   PINCTRL_PIN_GROUP("antsel18", mt7622_antsel18),
+   PINCTRL_PIN_GROUP("antsel19", mt7622_antsel19),
+  

Re: [PATCH v2] spi: spi-mtk-nor: fix timeout calculation overflow

2020-09-22 Thread Chuanhong Guo
On Tue, Sep 22, 2020 at 8:02 PM Mark Brown  wrote:
> (which we should pay attention to in the core for flash
> stuff but IIRC we didn't do that yet).

BTW we do have that taken care. spi_mem_adjust_op_size will
adjust the transfer size according to max_transfer/message_size
if no custom adjust_op_size hook is defined in the driver. If a custom
adjust_op_size is defined, the driver adjusts the transfer size for it's
exec_op hook. The size limit between exec_op and transfer_one_message
can be different. (this spi-mtk-nor is an example of that.)
-- 
Regards,
Chuanhong Guo


Re: [PATCH v2] spi: spi-mtk-nor: fix timeout calculation overflow

2020-09-22 Thread Chuanhong Guo
Hi!

On Tue, Sep 22, 2020 at 8:02 PM Mark Brown  wrote:
>
> On Tue, Sep 22, 2020 at 07:49:02PM +0800, Chuanhong Guo wrote:
>
> >   if ((op->data.dir == SPI_MEM_DATA_IN) &&
> >   mtk_nor_match_read(op)) {
> > + // limit size to prevent timeout calculation overflow
> > + if (op->data.nbytes > 0x40)
> > + op->data.nbytes = 0x40;
>
> If there's a limit on transfer sizes there should also be a
> max_transfer_size or max_message_size set (which we should pay attention
> to in the core for flash stuff but IIRC we didn't do that yet).

There's already a 6-byte max_message_size limit on this controller.
spi-mem dma read is the only operation which allows such a long transfer.

-- 
Regards,
Chuanhong Guo


[PATCH v2] spi: spi-mtk-nor: fix timeout calculation overflow

2020-09-22 Thread Chuanhong Guo
CLK_TO_US macro is used to calculate potential transfer time for various
timeout handling. However it overflows on transfer bigger than 512 bytes
because it first did (len * 8 * 100).
This controller typically operates at 45MHz. This patch did 2 things:
1. calculate clock / 100 first
2. add a 4M transfer size cap so that the final timeout in DMA reading
   doesn't overflow

Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller")
Cc: 
Signed-off-by: Chuanhong Guo 
---

Change since v1: fix transfer size cap to 4M

 drivers/spi/spi-mtk-nor.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 6e6ca2b8e6c82..62f5ff2779884 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -89,7 +89,7 @@
 // Buffered page program can do one 128-byte transfer
 #define MTK_NOR_PP_SIZE128
 
-#define CLK_TO_US(sp, clkcnt)  ((clkcnt) * 100 / sp->spi_freq)
+#define CLK_TO_US(sp, clkcnt)  DIV_ROUND_UP(clkcnt, sp->spi_freq / 
100)
 
 struct mtk_nor {
struct spi_controller *ctlr;
@@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, 
struct spi_mem_op *op)
if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
if ((op->data.dir == SPI_MEM_DATA_IN) &&
mtk_nor_match_read(op)) {
+   // limit size to prevent timeout calculation overflow
+   if (op->data.nbytes > 0x40)
+   op->data.nbytes = 0x40;
+
if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
(op->data.nbytes < MTK_NOR_DMA_ALIGN))
op->data.nbytes = 1;
-- 
2.26.2



Re: [PATCH] spi: spi-mtk-nor: fix timeout calculation overflow

2020-09-22 Thread Chuanhong Guo
On Tue, Sep 22, 2020 at 7:43 PM Chuanhong Guo  wrote:
>
> CLK_TO_US macro is used to calculate potential transfer time for various
> timeout handling. However it overflows on transfer bigger than 512 bytes
> because it first did (len * 8 * 100).
> This controller typically operates at 45MHz. This patch did 2 things:
> 1. calculate clock / 100 first
> 2. add a 4M transfer size cap so that the final timeout in DMA reading
>doesn't overflow
>
> Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller")
> Cc: 
> Signed-off-by: Chuanhong Guo 
> ---
>  drivers/spi/spi-mtk-nor.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
> index 6e6ca2b8e6c82..619313db42c0e 100644
> --- a/drivers/spi/spi-mtk-nor.c
> +++ b/drivers/spi/spi-mtk-nor.c
> @@ -89,7 +89,7 @@
>  // Buffered page program can do one 128-byte transfer
>  #define MTK_NOR_PP_SIZE128
>
> -#define CLK_TO_US(sp, clkcnt)  ((clkcnt) * 100 / sp->spi_freq)
> +#define CLK_TO_US(sp, clkcnt)  DIV_ROUND_UP(clkcnt, sp->spi_freq / 
> 100)
>
>  struct mtk_nor {
> struct spi_controller *ctlr;
> @@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, 
> struct spi_mem_op *op)
> if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
> if ((op->data.dir == SPI_MEM_DATA_IN) &&
> mtk_nor_match_read(op)) {
> +   // limit size to prevent timeout calculation overflow
> +   if (op->data.nbytes > 0x200)
> +       op->data.nbytes = 0x200;
> +

Sorry, wrong patch. This cap should be 4M not 32M. I'll send a v2 immediately.

-- 
Regards,
Chuanhong Guo


[PATCH] spi: spi-mtk-nor: fix timeout calculation overflow

2020-09-22 Thread Chuanhong Guo
CLK_TO_US macro is used to calculate potential transfer time for various
timeout handling. However it overflows on transfer bigger than 512 bytes
because it first did (len * 8 * 100).
This controller typically operates at 45MHz. This patch did 2 things:
1. calculate clock / 100 first
2. add a 4M transfer size cap so that the final timeout in DMA reading
   doesn't overflow

Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller")
Cc: 
Signed-off-by: Chuanhong Guo 
---
 drivers/spi/spi-mtk-nor.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 6e6ca2b8e6c82..619313db42c0e 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -89,7 +89,7 @@
 // Buffered page program can do one 128-byte transfer
 #define MTK_NOR_PP_SIZE128
 
-#define CLK_TO_US(sp, clkcnt)  ((clkcnt) * 100 / sp->spi_freq)
+#define CLK_TO_US(sp, clkcnt)  DIV_ROUND_UP(clkcnt, sp->spi_freq / 
100)
 
 struct mtk_nor {
struct spi_controller *ctlr;
@@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, 
struct spi_mem_op *op)
if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
if ((op->data.dir == SPI_MEM_DATA_IN) &&
mtk_nor_match_read(op)) {
+   // limit size to prevent timeout calculation overflow
+   if (op->data.nbytes > 0x200)
+   op->data.nbytes = 0x200;
+
if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
(op->data.nbytes < MTK_NOR_DMA_ALIGN))
op->data.nbytes = 1;
-- 
2.26.2



Re: [PATCH v2 2/5] spi: spi-mtk-nor: fix mishandled logics in checking SPI memory operation

2020-09-18 Thread Chuanhong Guo
Hi!

On Fri, Sep 18, 2020 at 9:09 PM Chuanhong Guo  wrote:
> On Fri, Sep 18, 2020 at 4:34 PM Ikjoon Jang  wrote:
> > [...]
> > +   switch (op->data.dir) {
> > +   case SPI_MEM_DATA_IN:
> > +   if (!mtk_nor_match_read(op))
> > +   return -EINVAL;
>
> You are changing the code logic here.
> mtk_nor_match_read checks if the operation can be executed
> using controller PIO/DMA reading. Even if it's not supported,
> we can still use PRG mode to execute the operation.
> One example of such an operation is SPI NOR SFDP reading.
> Your change breaks that which then breaks 1_2_2 and 1_4_4
> reading capability because spi-nor driver parses these op formats
> from SFDP table.

I just noticed that you already broke this in:
spi: spi-mtk-nor: support standard spi properties
Please also fix the same logic in mtk_nor_supports_op in your v3.

-- 
Regards,
Chuanhong Guo


Re: [PATCH v2 3/5] spi: spi-mtk-nor: use dma_alloc_coherent() for bounce buffer

2020-09-18 Thread Chuanhong Guo
d_dma to execute operation
3. call dma_unmap_single

read_bounce:
1. align reading length
2. call read_dma
3. call memcpy

>
>  static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op)
> @@ -439,11 +446,6 @@ static int mtk_nor_exec_op(struct spi_mem *mem, const 
> struct spi_mem_op *op)
> if (op->data.nbytes == 1) {
> mtk_nor_set_addr(sp, op);
> return mtk_nor_read_pio(sp, op);
> -   } else if (((ulong)(op->data.buf.in) &
> -   MTK_NOR_DMA_ALIGN_MASK)) {
> -   return mtk_nor_read_bounce(sp, op->addr.val,
> -  op->data.nbytes,
> -  op->data.buf.in);
> } else {
> return mtk_nor_read_dma(sp, op->addr.val,
> op->data.nbytes,
> @@ -654,6 +656,10 @@ static int mtk_nor_probe(struct platform_device *pdev)
> sp->dev = >dev;
> sp->spi_clk = spi_clk;
> sp->ctlr_clk = ctlr_clk;

There is extra memory allocation code for sp->buffer in mtk_nor_probe.
If you intend to replace this with dma_alloc_coherent you should
drop those devm_kmalloc code as well.

> +   sp->buffer = dma_alloc_coherent(>dev, MTK_NOR_BOUNCE_BUF_SIZE,
> +   >buffer_dma, GFP_KERNEL);

There's a devm variant: dmam_alloc_coherent(dev, size, dma_handle, gfp)

> +   if (!sp->buffer)
> +   return -ENOMEM;

This spi-nor controller requires all addresses to be 16-byte aligned.
Although it should be guaranteed by a usually way larger page
alignment address from dma_alloc_coherent I'd prefer an explicit
check for address alignment here rather than letting it probe
successfully and fail for every dma_read with bounce buffer.


>
> irq = platform_get_irq_optional(pdev, 0);
> if (irq < 0) {
> @@ -674,6 +680,8 @@ static int mtk_nor_probe(struct platform_device *pdev)
> ret = mtk_nor_init(sp);
>     if (ret < 0) {
> kfree(ctlr);
> +   dma_free_coherent(>dev, MTK_NOR_BOUNCE_BUF_SIZE,
> + sp->buffer, sp->buffer_dma);
> return ret;
> }
>
> @@ -692,6 +700,8 @@ static int mtk_nor_remove(struct platform_device *pdev)
>
> mtk_nor_disable_clk(sp);
>
> +   dma_free_coherent(>dev, MTK_NOR_BOUNCE_BUF_SIZE,
> + sp->buffer, sp->buffer_dma);
> return 0;
>  }
>
> --
> 2.28.0.681.g6f77f65b4e-goog
>


--
Regards,
Chuanhong Guo


Re: [PATCH v2 2/5] spi: spi-mtk-nor: fix mishandled logics in checking SPI memory operation

2020-09-18 Thread Chuanhong Guo
;
> +   break;
> +   default:
> +   break;
> }
> +   } else {
> +   u8 len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
> +
> +   if (len > MTK_NOR_PRG_MAX_SIZE)
> +   return -EINVAL;
> +   if (op->data.nbytes && !(MTK_NOR_PRG_MAX_SIZE - len))
> +   return -EINVAL;
> +   if (op->data.nbytes > (MTK_NOR_PRG_MAX_SIZE - len))
> +   op->data.nbytes = MTK_NOR_PRG_MAX_SIZE - len;
> }
>
> -   len = MTK_NOR_PRG_MAX_SIZE - op->cmd.nbytes - op->addr.nbytes -
> - op->dummy.nbytes;
> -   if (op->data.nbytes > len)
> -   op->data.nbytes = len;
> -
> return 0;
>  }
>
>  static bool mtk_nor_supports_op(struct spi_mem *mem,
> const struct spi_mem_op *op)
>  {
> -   size_t len;
> -
> if (op->cmd.buswidth != 1)
> return false;
>
> if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
> -   switch(op->data.dir) {
> +   switch (op->data.dir) {
> case SPI_MEM_DATA_IN:
> if (!mtk_nor_match_read(op))
> return false;
> @@ -226,11 +237,14 @@ static bool mtk_nor_supports_op(struct spi_mem *mem,
> default:
> break;
> }
> +   } else {
> +   u8 len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
> +
> +   if (len > MTK_NOR_PRG_MAX_SIZE)
> +   return false;
> +   if (op->data.nbytes && !(MTK_NOR_PRG_MAX_SIZE - len))
> +   return false;
> }
> -   len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
> -   if ((len > MTK_NOR_PRG_MAX_SIZE) ||
> -   ((op->data.nbytes) && (len == MTK_NOR_PRG_MAX_SIZE)))
> -   return false;
>
> return spi_mem_default_supports_op(mem, op);
>  }
> --
> 2.28.0.681.g6f77f65b4e-goog
>


-- 
Regards,
Chuanhong Guo


Re: [PATCH net-next v2 5/7] net: dsa: mt7530: Add the support of MT7531 switch

2020-08-20 Thread Chuanhong Guo
Hi!

On Thu, Aug 20, 2020 at 7:55 AM René van Dorst  wrote:
>
> With the current mainline code [1], the dsa code tries to detect how the MAC5
> is used. All the three modes are supported. MAC5 -> PHY0, MAC5 ->
> PHY4, MAC5 ->
> EXTERNAL PHY and MAC5 to external MAC.
>
> When MAC5 is a DSA port it skips settings the delay settings. See [2].
>
> Maybe you can use a similar concept.

Current detection relies on an incorrect assumption that mt753x switch
is always used with mtk_eth_soc. It's a really hacky solution to use
dt properties that don't belong to this switch at all and I think this
approach should not be followed further by future code.
The usage of mac5 should be explicitly defined as a dt property
under mt753x node.
-- 
Regards,
Chuanhong Guo


[PATCH][RFC] mtd: spinand: fix detection of GD5FxGQ4xA flash

2019-10-15 Thread Chuanhong Guo
GD5FxGQ4xA didn't follow the SPI spec to keep MISO low while slave is
reading, and instead MISO is kept high. As a result, the first byte
of id becomes 0xFF.
Since the first byte isn't supposed to be checked at all, this patch
just removed that check.

While at it, redo the comment above to better explain what's happening.

Fixes: cfd93d7c908e ("mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG")
Signed-off-by: Chuanhong Guo 
CC: Jeff Kletsky 
---
RFC:
I doubt whether this patch is a proper fix for the underlying problem:
The actual problem is that we have two different implementation of read id
command: One replies immediately after master sending 0x9f and the other
need to send 0x9f and an offset byte (found in winbond and early GD flashes.)
Current code only works if SPI master is properly implemented (i.e. keep MOSI
low while reading.)
I'm wondering if it worths to split the implementation of read_id into two
variants and assign corresponding ID tables to each variant, or we could
trust all SPI controllers and this fix is sufficient.

 drivers/mtd/nand/spi/gigadevice.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/spi/gigadevice.c 
b/drivers/mtd/nand/spi/gigadevice.c
index e99d425aa93f..ab0e53b09f0c 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -249,13 +249,14 @@ static int gigadevice_spinand_detect(struct 
spinand_device *spinand)
int ret;
 
/*
-* Earlier GDF5-series devices (A,E) return [0][MID][DID]
-* Later (F) devices return [MID][DID1][DID2]
+* Earlier GDF5-series devices (A,E) need sending an extra offset
+* byte before replying flash ID, so the first byte is undetermined.
+* Later (F) devices don't need that.
 */
 
if (id[0] == SPINAND_MFR_GIGADEVICE)
did = (id[1] << 8) + id[2];
-   else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
+   else if (id[1] == SPINAND_MFR_GIGADEVICE)
did = id[2];
else
return 0;
-- 
2.21.0



Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-18 Thread Chuanhong Guo
Hi!

On Sun, Aug 18, 2019 at 5:51 PM Oleksij Rempel  wrote:
>
> lets see more code:
> drivers/staging/mt7621-mmc/sd.c
> /* clock source for host: global */
> #if defined(CONFIG_SOC_MT7620)
> static u32 hclks[] = {4800}; /* +/- by chhung */
> #elif defined(CONFIG_SOC_MT7621)
> static u32 hclks[] = {5000}; /* +/- by chhung */
> #endif
>
> hm.. 50Mhz again. Feels like APB clock.
>
> ./drivers/staging/mt7621-dts/mt7621.dtsi
> cpuclock: cpuclock@0 {
> #clock-cells = <0>;
> compatible = "fixed-clock";
>
> /* FIXME: there should be way to detect this */
> clock-frequency = <88000>;
> };
>
> Your driver is trying to cover cpuclock
>
> sysclock: sysclock@0 {
> #clock-cells = <0>;
> compatible = "fixed-clock";
>
> /* This is normally 1/4 of cpuclock */
> clock-frequency = <22000>;
> };
>
> and most probably system clock alias "bus clock", most probably AHB.

This sysclock was the 50MHz clock in OpenWrt. It's set as "bus clock"
upstream by an incorrect commit.
As already stated in previous reply: I'm not going to make assumption
about clock plan using OpenWrt's device tree because it already
contains several mistakes on clocks. Since the upstream device tree
comes from there, I don't trust it either. You might want to check out
patch 6/6 in this series where the original author of this commit in
openwrt fixed some clocks and I ported it here.

> [...]
> > This debate goes nowhere. I've clarified the situation and made my
> > point. Of course I can't read through the ancient and heavily hacked
> > vendor kernel to figure out a clock plan myself.
>
> Ok, I provided you some productive technical hints how it should be
> done. I don't think mt7620 has better documentation then mt7621 and even
> in this case it was possible to make more or less good driver.

It does. A clock plan for mt7620 is available in MT7620 Programming
Guide, Page 14.

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-18 Thread Chuanhong Guo
On Sun, Aug 18, 2019 at 4:26 PM Chuanhong Guo  wrote:
>
> Hi!
>
> On Sun, Aug 18, 2019 at 3:59 PM Oleksij Rempel  wrote:
> >
> > Am 18.08.19 um 09:19 schrieb Chuanhong Guo:
> > > Hi!
> > >
> > > On Sun, Aug 18, 2019 at 2:10 PM Oleksij Rempel  
> > > wrote:
> > >>
> > >>>> We have at least 2 know registers:
> > >>>> SYSC_REG_CPLL_CLKCFG0 - it provides some information about boostrapped
> > >>>> refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
> > >>>> SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
> > >>>> all or some ip cores.
> > >>>> What is probably missing is a set of dividers for
> > >>>> each ip core. From your words it is not document.
> > >>>
> > >>> The specific missing part I was referring to, is parent clocks for
> > >>> every gates. I'm not going to assume this with current openwrt device
> > >>> tree because some peripherals doesn't have a clock binding at all or
> > >>> have a dummy one there.
> > >>
> > >> Ok, then I do not understand what is the motivation to upstream
> > >> something what is not nearly ready for use.
> > >
> > > Why isn't it "ready for use" then?
> > > A complete mt7621-pll driver will contain two parts:
> > > 1. A clock provider which outputs several clocks
> > > 2. A clock gate with parent clocks properly configured
> > >
> > > Two clocks provided here are just two clocks that can't be controlled
> > > in kernel no matter where it goes (arch/mips/ralink or drivers/clk).
> > > Having a working CPU clock provider is better than defining a fixed
> > > clock in dts because CPU clock can be controlled by bootloader.
> > > (BTW description for CPU PLL register is also missing in datasheet.)
> > > Clock gate is an unrelated part and there is no information to
> > > properly implement it unless MTK decided to release a clock plan
> > > somehow.
> >
> > With other words, your complete system is running with unknown clock
> > rates.
>
> And without this patchset the complete system is running with unknown
> clock and, even worse, we make assumptions about what clock bootloader
> uses, hardcoded it in dts and hope it is the correct value.
>
> > The source clock in the clock three can be configured differently
> > by bootloader but you don't know how it is done how and it is not
> > documented.
>
> Actually, I don't know about this and I didn't wrote the original
> clock calculation code. I just ported it from downstream OpenWrt
> kernel. Here's a piece of code from Mediatek's SDK kernel:
>
> case 0:
> reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x44));
> cpu_fdiv = ((reg >> 8) & 0x1F);
> cpu_ffrac = (reg & 0x1F);
> mips_cpu_feq = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
> break;
> case 1: //CPU PLL
> reg = (*(volatile u32 *)(RALINK_MEMCTRL_BASE + 0x648));
> fbdiv = ((reg >> 4) & 0x7F) + 1;
> reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10));
> reg = (reg >> 6) & 0x7;
> if(reg >= 6) { //25Mhz Xtal
> mips_cpu_feq = 25 * fbdiv * 1000 * 1000;
> } else if(reg >=3) { //40Mhz Xtal
> mips_cpu_feq = 20 * fbdiv * 1000 * 1000;
> } else { // 20Mhz Xtal
> /* TODO */
> }
> break;
>
>
>
> >
> > >> This code is currently on prototyping phase
> > >
> > > Code for clock calculation is done, not "prototyping".
> > >
> > >> It means, we cannot expect that this driver will be fixed any time soon.
> > >
> > > I think clock gating is a separated feature instead of a broken part
> > > that has to be fixed.
> >
> > Ok, i would agree with it. But from what you said, this feature will be
> > never implemented.
> >
> > So, I repeat my question. What is the point to upstream code for a
> > system, which has not enough information to get proper clock rate even
> > for uart? or is uart running with cpu or bus clock rate?
>
> uart runs of a fixed 50MHz clock according to another piece of code
> from MTK SDK:
> (a pastebin version here for better readability. This specific
> question has nothing to do with patch reviewing and doesn't need to be
> preserved in mail forever.)
> https://paste.ubuntu.com/p/fYmtDFW9nh/
>
> I could ask the same question:
> What is the point of upstreaming an incomplete MT7621 support in the
> first place? Current MT7621 support in upstream kernel works only for
> mt7621a not mt7621s and it runs of unknown clocks. These kind of code
> should stay in downstream projects like OpenWrt forever isn't it?

And in fact you've upstreamed a broken ag71xx driver anyway.

This debate goes nowhere. I've clarified the situation and made my
point. Of course I can't read through the ancient and heavily hacked
vendor kernel to figure out a clock plan myself.

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-18 Thread Chuanhong Guo
Hi!

On Sun, Aug 18, 2019 at 3:59 PM Oleksij Rempel  wrote:
>
> Am 18.08.19 um 09:19 schrieb Chuanhong Guo:
> > Hi!
> >
> > On Sun, Aug 18, 2019 at 2:10 PM Oleksij Rempel  
> > wrote:
> >>
> >>>> We have at least 2 know registers:
> >>>> SYSC_REG_CPLL_CLKCFG0 - it provides some information about boostrapped
> >>>> refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
> >>>> SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
> >>>> all or some ip cores.
> >>>> What is probably missing is a set of dividers for
> >>>> each ip core. From your words it is not document.
> >>>
> >>> The specific missing part I was referring to, is parent clocks for
> >>> every gates. I'm not going to assume this with current openwrt device
> >>> tree because some peripherals doesn't have a clock binding at all or
> >>> have a dummy one there.
> >>
> >> Ok, then I do not understand what is the motivation to upstream
> >> something what is not nearly ready for use.
> >
> > Why isn't it "ready for use" then?
> > A complete mt7621-pll driver will contain two parts:
> > 1. A clock provider which outputs several clocks
> > 2. A clock gate with parent clocks properly configured
> >
> > Two clocks provided here are just two clocks that can't be controlled
> > in kernel no matter where it goes (arch/mips/ralink or drivers/clk).
> > Having a working CPU clock provider is better than defining a fixed
> > clock in dts because CPU clock can be controlled by bootloader.
> > (BTW description for CPU PLL register is also missing in datasheet.)
> > Clock gate is an unrelated part and there is no information to
> > properly implement it unless MTK decided to release a clock plan
> > somehow.
>
> With other words, your complete system is running with unknown clock
> rates.

And without this patchset the complete system is running with unknown
clock and, even worse, we make assumptions about what clock bootloader
uses, hardcoded it in dts and hope it is the correct value.

> The source clock in the clock three can be configured differently
> by bootloader but you don't know how it is done how and it is not
> documented.

Actually, I don't know about this and I didn't wrote the original
clock calculation code. I just ported it from downstream OpenWrt
kernel. Here's a piece of code from Mediatek's SDK kernel:

case 0:
reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x44));
cpu_fdiv = ((reg >> 8) & 0x1F);
cpu_ffrac = (reg & 0x1F);
mips_cpu_feq = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
break;
case 1: //CPU PLL
reg = (*(volatile u32 *)(RALINK_MEMCTRL_BASE + 0x648));
fbdiv = ((reg >> 4) & 0x7F) + 1;
reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10));
reg = (reg >> 6) & 0x7;
if(reg >= 6) { //25Mhz Xtal
mips_cpu_feq = 25 * fbdiv * 1000 * 1000;
} else if(reg >=3) { //40Mhz Xtal
mips_cpu_feq = 20 * fbdiv * 1000 * 1000;
} else { // 20Mhz Xtal
/* TODO */
}
break;



>
> >> This code is currently on prototyping phase
> >
> > Code for clock calculation is done, not "prototyping".
> >
> >> It means, we cannot expect that this driver will be fixed any time soon.
> >
> > I think clock gating is a separated feature instead of a broken part
> > that has to be fixed.
>
> Ok, i would agree with it. But from what you said, this feature will be
> never implemented.
>
> So, I repeat my question. What is the point to upstream code for a
> system, which has not enough information to get proper clock rate even
> for uart? or is uart running with cpu or bus clock rate?

uart runs of a fixed 50MHz clock according to another piece of code
from MTK SDK:
(a pastebin version here for better readability. This specific
question has nothing to do with patch reviewing and doesn't need to be
preserved in mail forever.)
https://paste.ubuntu.com/p/fYmtDFW9nh/

I could ask the same question:
What is the point of upstreaming an incomplete MT7621 support in the
first place? Current MT7621 support in upstream kernel works only for
mt7621a not mt7621s and it runs of unknown clocks. These kind of code
should stay in downstream projects like OpenWrt forever isn't it?

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-18 Thread Chuanhong Guo
Hi!

On Sun, Aug 18, 2019 at 2:10 PM Oleksij Rempel  wrote:
>
> >> We have at least 2 know registers:
> >> SYSC_REG_CPLL_CLKCFG0 - it provides some information about boostrapped
> >> refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
> >> SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
> >> all or some ip cores.
> >> What is probably missing is a set of dividers for
> >> each ip core. From your words it is not document.
> >
> > The specific missing part I was referring to, is parent clocks for
> > every gates. I'm not going to assume this with current openwrt device
> > tree because some peripherals doesn't have a clock binding at all or
> > have a dummy one there.
>
> Ok, then I do not understand what is the motivation to upstream
> something what is not nearly ready for use.

Why isn't it "ready for use" then?
A complete mt7621-pll driver will contain two parts:
1. A clock provider which outputs several clocks
2. A clock gate with parent clocks properly configured

Two clocks provided here are just two clocks that can't be controlled
in kernel no matter where it goes (arch/mips/ralink or drivers/clk).
Having a working CPU clock provider is better than defining a fixed
clock in dts because CPU clock can be controlled by bootloader.
(BTW description for CPU PLL register is also missing in datasheet.)
Clock gate is an unrelated part and there is no information to
properly implement it unless MTK decided to release a clock plan
somehow.

> This code is currently on prototyping phase

Code for clock calculation is done, not "prototyping".

> It means, we cannot expect that this driver will be fixed any time soon.

I think clock gating is a separated feature instead of a broken part
that has to be fixed.

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-17 Thread Chuanhong Guo
Hi!

On Sun, Aug 18, 2019 at 2:06 AM Oleksij Rempel  wrote:
> >> SYSC_REG_CPLL_CLKCFG1 register is a clock gate controller. It is used to 
> >> enable or disable clocks.
> >> Jist wild assumption. All peripheral devices are suing bus clock.
> >
> > This assumption is incorrect. When this patchset is applied in
> > OpenWrt, I asked the author why there's still a fixed clock in
> > mt7621.dtsi, He told me that there's another clock for those unchanged
> > peripherals and he doesn't have time to write a clock provider for it.
>
> Can you please provide a link to this patch or email.

This discussion is in Chinese and using an IM software so there's no
link available.

> We have at least 2 know registers:
> SYSC_REG_CPLL_CLKCFG0 - it provides some information about boostrapped
> refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
> SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
> all or some ip cores.
> What is probably missing is a set of dividers for
> each ip core. From your words it is not document.

The specific missing part I was referring to, is parent clocks for
every gates. I'm not going to assume this with current openwrt device
tree because some peripherals doesn't have a clock binding at all or
have a dummy one there.

>
> With this information the clk driver will provide gate functionality and
> a set of hardcoded clocks. With this driver will work part of power
> management and nice devicetree without fixed clocks.

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-17 Thread Chuanhong Guo
Hi!

On Sat, Aug 17, 2019 at 11:40 PM Oleksij Rempel  wrote:

> In provided link [0] the  ralink_clk_init function is reading 
> SYSC_REG_CPLL_CLKCFG0 R/W register.
> This register is used to determine clock source,  clock freq and CPU or bus 
> clocks.

This register should only be changed by bootloader, not kernel. So
it's read-only in kernel's perspective.

> SYSC_REG_CPLL_CLKCFG1 register is a clock gate controller. It is used to 
> enable or disable clocks.
> Jist wild assumption. All peripheral devices are suing bus clock.

This assumption is incorrect. When this patchset is applied in
OpenWrt, I asked the author why there's still a fixed clock in
mt7621.dtsi, He told me that there's another clock for those unchanged
peripherals and he doesn't have time to write a clock provider for it.
I don't know how many undocumented clocks are there since this piece
of info is missing in datasheet.

>
> IMO - this information is enough to create full blown 
> drivers/clk/mediatek/clk-mt7621.c

And this information isn't enough because the assumption above is incorrect :P

Regards,
Chuanhong Guo


Re: [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-08-17 Thread Chuanhong Guo
Hi!

On Tue, Aug 13, 2019 at 11:51 PM Rob Herring  wrote:
> [...]
> > +Example:
> > + pll {
> > + compatible = "mediatek,mt7621-pll";
>
> You didn't answer Stephen's question on v1.

I thought he was asking why there's a syscon in compatible string. I
noticed that the syscon in my previous patch is a copy-paste error
from elsewhere and dropped it.

>
> Based on this binding, there is no way to control/program the PLL. Is
> this part of some IP block?

The entire section is called "system control" in datasheet and is
occupied in arch/mips/ralink/mt7621.c [0]
Two clocks provided here is determined by reading some read-only
registers in this part.
There's another register in this section providing clock gates for
every peripherals, but MTK doesn't provide a clock plan in their
datasheet. I can't determine corresponding clock frequencies for every
peripherals, thus unable to write a working clock driver.

>
> > +
> > + #clock-cells = <1>;
> > +     clock-output-names = "cpu", "bus";
> > + };
> > --
> > 2.21.0
> >

Regards,
Chuanhong Guo

[0] 
https://elixir.bootlin.com/linux/latest/source/arch/mips/ralink/mt7621.c#L156


[PATCH v2 5/6] staging: mt7621-dts: fix register range of memc node in mt7621.dtsi

2019-07-23 Thread Chuanhong Guo
The memc node from mt7621.dtsi has incorrect register resource.
Fix it according to the programming guide.

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
---

Change since v1: None.

 drivers/staging/mt7621-dts/mt7621.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi 
b/drivers/staging/mt7621-dts/mt7621.dtsi
index a4c08110094b..d89d68ffa7bc 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -138,7 +138,7 @@
 
memc: memc@5000 {
compatible = "mtk,mt7621-memc";
-   reg = <0x300 0x100>;
+   reg = <0x5000 0x1000>;
};
 
cpc: cpc@1fbf {
-- 
2.21.0



[PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation

2019-07-23 Thread Chuanhong Guo
This commit adds device tree binding documentation for MT7621
PLL controller.

Signed-off-by: Chuanhong Guo 
---

Change since v1:
drop useless syscon in compatible string

 .../bindings/clock/mediatek,mt7621-pll.txt | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt

diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt 
b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
new file mode 100644
index ..7dcfbd5283e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
@@ -0,0 +1,18 @@
+Binding for Mediatek MT7621 PLL controller
+
+The PLL controller provides the 2 main clocks of the SoC: CPU and BUS.
+
+Required Properties:
+- compatible: has to be "mediatek,mt7621-pll"
+- #clock-cells: has to be one
+
+Optional properties:
+- clock-output-names: should be "cpu", "bus"
+
+Example:
+   pll {
+   compatible = "mediatek,mt7621-pll";
+
+   #clock-cells = <1>;
+   clock-output-names = "cpu", "bus";
+   };
-- 
2.21.0



[PATCH v2 6/6] staging: mt7621-dts: add dt nodes for mt7621-pll

2019-07-23 Thread Chuanhong Guo
This commit adds device-tree node for mt7621-pll and use its clocks
accordingly.

Signed-off-by: Chuanhong Guo 
---

Changes since v1:
1. drop cpuclock node in gbpc1.dts
2. drop syscon in mt7621-pll node

 drivers/staging/mt7621-dts/gbpc1.dts   |  5 -
 drivers/staging/mt7621-dts/mt7621.dtsi | 15 +++
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/mt7621-dts/gbpc1.dts 
b/drivers/staging/mt7621-dts/gbpc1.dts
index 1fb560ff059c..d94b73243268 100644
--- a/drivers/staging/mt7621-dts/gbpc1.dts
+++ b/drivers/staging/mt7621-dts/gbpc1.dts
@@ -106,11 +106,6 @@
clock-frequency = <22500>;
 };
 
- {
-   compatible = "fixed-clock";
-   clock-frequency = <9>;
-};
-
  {
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi 
b/drivers/staging/mt7621-dts/mt7621.dtsi
index d89d68ffa7bc..7b82f7f70404 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,4 +1,5 @@
 #include 
+#include 
 #include 
 
 / {
@@ -27,12 +28,11 @@
serial0 = 
};
 
-   cpuclock: cpuclock@0 {
-   #clock-cells = <0>;
-   compatible = "fixed-clock";
+   pll: pll {
+   compatible = "mediatek,mt7621-pll";
 
-   /* FIXME: there should be way to detect this */
-   clock-frequency = <88000>;
+   #clock-cells = <1>;
+   clock-output-names = "cpu", "bus";
};
 
sysclock: sysclock@0 {
@@ -155,7 +155,6 @@
compatible = "ns16550a";
reg = <0xc00 0x100>;
 
-   clocks = <>;
clock-frequency = <5000>;
 
interrupt-parent = <>;
@@ -172,7 +171,7 @@
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
 
-   clocks = <>;
+   clocks = < MT7621_CLK_BUS>;
 
resets = < 18>;
reset-names = "spi";
@@ -372,7 +371,7 @@
timer {
compatible = "mti,gic-timer";
interrupts = ;
-   clocks = <>;
+   clocks = < MT7621_CLK_CPU>;
};
};
 
-- 
2.21.0



[PATCH v2 3/6] MIPS: ralink: add clock device providing cpu/bus clock for mt7621

2019-07-23 Thread Chuanhong Guo
For a long time the mt7621 uses a fixed cpu clock which causes a problem
if the cpu frequency is not 880MHz.
This patch adds cpu/bus clock calculation code and binds clocks to
mt7621-pll node.

Ported from OpenWrt:
c7ca224299 ramips: fix cpu clock of mt7621 and add dt clk devices

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
---

Changes since v1:
1. split patch.
2. calculate clocks using the function called by CLK_OF_DECLARE
   drop direct function call in timer-gic.c of ralink_clk_init
3. drop assignment of mips-hpt-frequency

 arch/mips/include/asm/mach-ralink/mt7621.h | 20 ++
 arch/mips/ralink/mt7621.c  | 77 ++
 2 files changed, 97 insertions(+)

diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h 
b/arch/mips/include/asm/mach-ralink/mt7621.h
index 65483a4681ab..51a6e51aef3f 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -17,6 +17,10 @@
 #define SYSC_REG_CHIP_REV  0x0c
 #define SYSC_REG_SYSTEM_CONFIG00x10
 #define SYSC_REG_SYSTEM_CONFIG10x14
+#define SYSC_REG_CLKCFG0   0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+
+#define MEMC_REG_CPU_PLL   0x648
 
 #define CHIP_REV_PKG_MASK  0x1
 #define CHIP_REV_PKG_SHIFT 16
@@ -24,6 +28,22 @@
 #define CHIP_REV_VER_SHIFT 8
 #define CHIP_REV_ECO_MASK  0xf
 
+#define XTAL_MODE_SEL_MASK 0x7
+#define XTAL_MODE_SEL_SHIFT6
+
+#define CPU_CLK_SEL_MASK   0x3
+#define CPU_CLK_SEL_SHIFT  30
+
+#define CUR_CPU_FDIV_MASK  0x1f
+#define CUR_CPU_FDIV_SHIFT 8
+#define CUR_CPU_FFRAC_MASK 0x1f
+#define CUR_CPU_FFRAC_SHIFT0
+
+#define CPU_PLL_PREDIV_MASK0x3
+#define CPU_PLL_PREDIV_SHIFT   12
+#define CPU_PLL_FBDIV_MASK 0x7f
+#define CPU_PLL_FBDIV_SHIFT4
+
 #define MT7621_DRAM_BASE0x0
 #define MT7621_DDR2_SIZE_MIN   32
 #define MT7621_DDR2_SIZE_MAX   256
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index ba39f3f3a7c7..baf9033a67b4 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -7,12 +7,16 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -103,11 +107,84 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
{ 0 }
 };
 
+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+   .clks = clks,
+   .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
panic("Cannot detect cpc address");
 }
 
+static struct clk *__init mt7621_add_sys_clkdev(
+   const char *id, unsigned long rate)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+   if (IS_ERR(clk))
+   panic("failed to allocate %s clock structure", id);
+
+   err = clk_register_clkdev(clk, id, NULL);
+   if (err)
+   panic("unable to register %s clock device", id);
+
+   return clk;
+}
+
+static void __init mt7621_clocks_init(struct device_node *np)
+{
+   const static u32 prediv_tbl[] = {0, 1, 2, 2};
+   u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+   u32 pll, prediv, fbdiv;
+   u32 xtal_clk, cpu_clk, bus_clk;
+
+   syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+   xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
+
+   clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+   clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+   curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+   ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+   ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+   if (xtal_sel <= 2)
+   xtal_clk = 20 * 1000 * 1000;
+   else if (xtal_sel <= 5)
+   xtal_clk = 40 * 1000 * 1000;
+   else
+   xtal_clk = 25 * 1000 * 1000;
+
+   switch (clk_sel) {
+   case 0:
+   cpu_clk = 500 * 1000 * 1000;
+   break;
+   case 1:
+   pll = rt_memc_r32(MEMC_REG_CPU_PLL);
+   fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK;
+   prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK;
+   cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
+   break;
+   default:
+   cpu_clk = xtal_clk;
+   }
+
+   cpu_clk = cpu_clk / ffiv * ffrac;
+   bus_clk = cpu_clk / 4;
+
+   clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk);
+   clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk);
+

[PATCH v2 0/6] MIPS: ralink: add CPU clock detection for MT7621

2019-07-23 Thread Chuanhong Guo
This patchset ports CPU clock detection for MT7621 from OpenWrt.

Last time I sent this, I forgot to add an binding include which
caused a compile error and the patch doesn't stay in linux-next.

This patchset resent the first two commits and also added binding
documentation for mt7621-pll and used it in mt7621-dts at
drivers/staging.

Changes since v1:
1. changed commit title prefix for dt include
2. split the patch adding clock node (details in that patch body)
3. drop useless syscon in dt documentation
4. drop cpuclock node for gbpc1

Chuanhong Guo (6):
  dt-bindings: clock: add dt binding header for mt7621-pll
  MIPS: ralink: drop ralink_clk_init for mt7621
  MIPS: ralink: add clock device providing cpu/bus clock for mt7621
  dt: bindings: add mt7621-pll dt binding documentation
  staging: mt7621-dts: fix register range of memc node in mt7621.dtsi
  staging: mt7621-dts: add dt nodes for mt7621-pll

 .../bindings/clock/mediatek,mt7621-pll.txt| 18 
 arch/mips/include/asm/mach-ralink/mt7621.h| 20 
 arch/mips/ralink/mt7621.c | 98 +--
 drivers/staging/mt7621-dts/gbpc1.dts  |  5 -
 drivers/staging/mt7621-dts/mt7621.dtsi| 17 ++--
 include/dt-bindings/clock/mt7621-clk.h| 14 +++
 6 files changed, 126 insertions(+), 46 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
 create mode 100644 include/dt-bindings/clock/mt7621-clk.h

-- 
2.21.0



[PATCH v2 2/6] MIPS: ralink: drop ralink_clk_init for mt7621

2019-07-23 Thread Chuanhong Guo
This function isn't called anywhere. just drop it.

Signed-off-by: Chuanhong Guo 
---
Change since v1:
New patch. Split from:
  "MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices"

 arch/mips/ralink/mt7621.c | 43 ---
 1 file changed, 43 deletions(-)

diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 9415be0d57b8..ba39f3f3a7c7 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -18,11 +18,6 @@
 
 #include "common.h"
 
-#define SYSC_REG_SYSCFG0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL(BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1 1
 #define MT7621_GPIO_MODE_I2C   2
 #define MT7621_GPIO_MODE_UART3_MASK0x3
@@ -113,44 +108,6 @@ phys_addr_t mips_cpc_default_phys_base(void)
panic("Cannot detect cpc address");
 }
 
-void __init ralink_clk_init(void)
-{
-   int cpu_fdiv = 0;
-   int cpu_ffrac = 0;
-   int fbdiv = 0;
-   u32 clk_sts, syscfg;
-   u8 clk_sel = 0, xtal_mode;
-   u32 cpu_clk;
-
-   if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-   clk_sel = 1;
-
-   switch (clk_sel) {
-   case 0:
-   clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-   cpu_fdiv = ((clk_sts >> 8) & 0x1F);
-   cpu_ffrac = (clk_sts & 0x1F);
-   cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
-   break;
-
-   case 1:
-   fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
-   syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
-   xtal_mode = (syscfg >> 6) & 0x7;
-   if (xtal_mode >= 6) {
-   /* 25Mhz Xtal */
-   cpu_clk = 25 * fbdiv * 1000 * 1000;
-   } else if (xtal_mode >= 3) {
-   /* 40Mhz Xtal */
-   cpu_clk = 40 * fbdiv * 1000 * 1000;
-   } else {
-   /* 20Mhz Xtal */
-   cpu_clk = 20 * fbdiv * 1000 * 1000;
-   }
-   break;
-   }
-}
-
 void __init ralink_of_remap(void)
 {
rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
-- 
2.21.0



[PATCH v2 1/6] dt-bindings: clock: add dt binding header for mt7621-pll

2019-07-23 Thread Chuanhong Guo
This patch adds dt binding header for mediatek,mt7621-pll

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
Reviewed-by: Rob Herring 
---
Change since v1:
Change commit title prefix.

 include/dt-bindings/clock/mt7621-clk.h | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt7621-clk.h

diff --git a/include/dt-bindings/clock/mt7621-clk.h 
b/include/dt-bindings/clock/mt7621-clk.h
new file mode 100644
index ..a29e14ee2efe
--- /dev/null
+++ b/include/dt-bindings/clock/mt7621-clk.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Weijie Gao 
+ */
+
+#ifndef __DT_BINDINGS_MT7621_CLK_H
+#define __DT_BINDINGS_MT7621_CLK_H
+
+#define MT7621_CLK_CPU 0
+#define MT7621_CLK_BUS 1
+
+#define MT7621_CLK_MAX 2
+
+#endif /* __DT_BINDINGS_MT7621_CLK_H */
-- 
2.21.0



Re: [PATCH 4/5] staging: mt7621-dts: add dt nodes for mt7621-pll

2019-07-10 Thread Chuanhong Guo
On Wed, Jul 10, 2019 at 2:22 AM Chuanhong Guo  wrote:
>
> This commit adds device-tree node for mt7621-pll and use its clock
> accordingly.
>
> Signed-off-by: Chuanhong Guo 

Oops. Please ignore this single patch for now. I forgot to drop
cpuclock node in drivers/staging/mt7621-dts/gbpc1.dts
I'll resend this patch with changes for gbpc1.dts after the other four
patches are applied.

> ---
>  drivers/staging/mt7621-dts/mt7621.dtsi | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi 
> b/drivers/staging/mt7621-dts/mt7621.dtsi
> index a4c08110094b..12717f570ceb 100644
> --- a/drivers/staging/mt7621-dts/mt7621.dtsi
> +++ b/drivers/staging/mt7621-dts/mt7621.dtsi
> @@ -1,4 +1,5 @@
>  #include 
> +#include 
>  #include 
>
>  / {
> @@ -27,12 +28,11 @@
> serial0 = 
> };
>
> -   cpuclock: cpuclock@0 {
> -   #clock-cells = <0>;
> -   compatible = "fixed-clock";
> +   pll: pll {
> +   compatible = "mediatek,mt7621-pll", "syscon";
>
> -   /* FIXME: there should be way to detect this */
> -   clock-frequency = <88000>;
> +   #clock-cells = <1>;
> +   clock-output-names = "cpu", "bus";
> };
>
> sysclock: sysclock@0 {
> @@ -155,7 +155,6 @@
> compatible = "ns16550a";
> reg = <0xc00 0x100>;
>
> -   clocks = <>;
> clock-frequency = <5000>;
>
> interrupt-parent = <>;
> @@ -172,7 +171,7 @@
> compatible = "ralink,mt7621-spi";
> reg = <0xb00 0x100>;
>
> -   clocks = <>;
> +   clocks = < MT7621_CLK_BUS>;
>
> resets = < 18>;
> reset-names = "spi";
> @@ -372,7 +371,7 @@
> timer {
> compatible = "mti,gic-timer";
> interrupts = ;
> -   clocks = <>;
> +   clocks = < MT7621_CLK_CPU>;
> };
> };
>
> --
> 2.21.0
>


[PATCH 2/5] MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices

2019-07-09 Thread Chuanhong Guo
For a long time the mt7621 uses a fixed cpu clock which causes a problem
if the cpu frequency is not 880MHz.

This patch fixes the cpu clock calculation and adds the cpu/bus clkdev
which will be used in dts.

Ported from OpenWrt:
c7ca224299 ramips: fix cpu clock of mt7621 and add dt clk devices

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
---
 arch/mips/include/asm/mach-ralink/mt7621.h |  20 
 arch/mips/ralink/mt7621.c  | 102 ++---
 arch/mips/ralink/timer-gic.c   |   4 +-
 3 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h 
b/arch/mips/include/asm/mach-ralink/mt7621.h
index 65483a4681ab..51a6e51aef3f 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -17,6 +17,10 @@
 #define SYSC_REG_CHIP_REV  0x0c
 #define SYSC_REG_SYSTEM_CONFIG00x10
 #define SYSC_REG_SYSTEM_CONFIG10x14
+#define SYSC_REG_CLKCFG0   0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+
+#define MEMC_REG_CPU_PLL   0x648
 
 #define CHIP_REV_PKG_MASK  0x1
 #define CHIP_REV_PKG_SHIFT 16
@@ -24,6 +28,22 @@
 #define CHIP_REV_VER_SHIFT 8
 #define CHIP_REV_ECO_MASK  0xf
 
+#define XTAL_MODE_SEL_MASK 0x7
+#define XTAL_MODE_SEL_SHIFT6
+
+#define CPU_CLK_SEL_MASK   0x3
+#define CPU_CLK_SEL_SHIFT  30
+
+#define CUR_CPU_FDIV_MASK  0x1f
+#define CUR_CPU_FDIV_SHIFT 8
+#define CUR_CPU_FFRAC_MASK 0x1f
+#define CUR_CPU_FFRAC_SHIFT0
+
+#define CPU_PLL_PREDIV_MASK0x3
+#define CPU_PLL_PREDIV_SHIFT   12
+#define CPU_PLL_FBDIV_MASK 0x7f
+#define CPU_PLL_FBDIV_SHIFT4
+
 #define MT7621_DRAM_BASE0x0
 #define MT7621_DDR2_SIZE_MIN   32
 #define MT7621_DDR2_SIZE_MAX   256
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 9415be0d57b8..31158b88bcb6 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -7,22 +7,22 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "common.h"
 
-#define SYSC_REG_SYSCFG0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL(BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1 1
 #define MT7621_GPIO_MODE_I2C   2
 #define MT7621_GPIO_MODE_UART3_MASK0x3
@@ -108,49 +108,89 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
{ 0 }
 };
 
+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+   .clks = clks,
+   .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
panic("Cannot detect cpc address");
 }
 
+static struct clk *__init mt7621_add_sys_clkdev(
+   const char *id, unsigned long rate)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+   if (IS_ERR(clk))
+   panic("failed to allocate %s clock structure", id);
+
+   err = clk_register_clkdev(clk, id, NULL);
+   if (err)
+   panic("unable to register %s clock device", id);
+
+   return clk;
+}
+
 void __init ralink_clk_init(void)
 {
-   int cpu_fdiv = 0;
-   int cpu_ffrac = 0;
-   int fbdiv = 0;
-   u32 clk_sts, syscfg;
-   u8 clk_sel = 0, xtal_mode;
-   u32 cpu_clk;
+   const static u32 prediv_tbl[] = {0, 1, 2, 2};
+   u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+   u32 pll, prediv, fbdiv;
+   u32 xtal_clk, cpu_clk, bus_clk;
+
+   syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+   xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
 
-   if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-   clk_sel = 1;
+   clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+   clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+   curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+   ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+   ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+   if (xtal_sel <= 2)
+   xtal_clk = 20 * 1000 * 1000;
+   else if (xtal_sel <= 5)
+   xtal_clk = 40 * 1000 * 1000;
+   else
+   xtal_clk = 25 * 1000 * 1000;
 
switch (clk_sel) {
case 0:
-   clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-   cpu_fdiv = ((clk_sts >> 8) & 0x1F);
-   cpu_ffrac = (clk_sts & 0x1F);
-   cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
+  

[PATCH 3/5] dt: bindings: add mt7621-pll dt binding documentation

2019-07-09 Thread Chuanhong Guo
This commit adds device tree binding documentation for MT7621
PLL controller.

Signed-off-by: Chuanhong Guo 
---
 .../bindings/clock/mediatek,mt7621-pll.txt| 19 +++
 1 file changed, 19 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt

diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt 
b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
new file mode 100644
index ..05c15062cd20
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
@@ -0,0 +1,19 @@
+Binding for Mediatek MT7621 PLL controller
+
+The PLL controller provides the 2 main clocks of the SoC: CPU and BUS.
+
+Required Properties:
+- compatible: has to be "mediatek,mt7621-pll"
+- #clock-cells: has to be one
+
+Optional properties:
+- clock-output-names: should be "cpu", "bus"
+
+Example:
+   pll {
+   compatible = "mediatek,mt7621-pll", "syscon";
+
+   #clock-cells = <1>;
+   clock-output-names = "cpu", "bus";
+   };
+
-- 
2.21.0



[PATCH 5/5] staging: mt7621-dts: fix register range of memc node in mt7621.dtsi

2019-07-09 Thread Chuanhong Guo
The memc node from mt7621.dtsi has incorrect register resource.
Fix it according to the programming guide.

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
---
 drivers/staging/mt7621-dts/mt7621.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi 
b/drivers/staging/mt7621-dts/mt7621.dtsi
index 12717f570ceb..ac9189276590 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -138,7 +138,7 @@
 
memc: memc@5000 {
compatible = "mtk,mt7621-memc";
-   reg = <0x300 0x100>;
+   reg = <0x5000 0x1000>;
};
 
cpc: cpc@1fbf {
-- 
2.21.0



[PATCH 4/5] staging: mt7621-dts: add dt nodes for mt7621-pll

2019-07-09 Thread Chuanhong Guo
This commit adds device-tree node for mt7621-pll and use its clock
accordingly.

Signed-off-by: Chuanhong Guo 
---
 drivers/staging/mt7621-dts/mt7621.dtsi | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi 
b/drivers/staging/mt7621-dts/mt7621.dtsi
index a4c08110094b..12717f570ceb 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,4 +1,5 @@
 #include 
+#include 
 #include 
 
 / {
@@ -27,12 +28,11 @@
serial0 = 
};
 
-   cpuclock: cpuclock@0 {
-   #clock-cells = <0>;
-   compatible = "fixed-clock";
+   pll: pll {
+   compatible = "mediatek,mt7621-pll", "syscon";
 
-   /* FIXME: there should be way to detect this */
-   clock-frequency = <88000>;
+   #clock-cells = <1>;
+   clock-output-names = "cpu", "bus";
};
 
sysclock: sysclock@0 {
@@ -155,7 +155,6 @@
compatible = "ns16550a";
reg = <0xc00 0x100>;
 
-   clocks = <>;
clock-frequency = <5000>;
 
interrupt-parent = <>;
@@ -172,7 +171,7 @@
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
 
-   clocks = <>;
+   clocks = < MT7621_CLK_BUS>;
 
resets = < 18>;
reset-names = "spi";
@@ -372,7 +371,7 @@
timer {
compatible = "mti,gic-timer";
interrupts = ;
-   clocks = <>;
+   clocks = < MT7621_CLK_CPU>;
};
};
 
-- 
2.21.0



[PATCH 1/5] MIPS: ralink: add dt binding header for mt7621-pll

2019-07-09 Thread Chuanhong Guo
This patch adds dt binding header for mediatek,mt7621-pll

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
Reviewed-by: Rob Herring 
---
 include/dt-bindings/clock/mt7621-clk.h | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt7621-clk.h

diff --git a/include/dt-bindings/clock/mt7621-clk.h 
b/include/dt-bindings/clock/mt7621-clk.h
new file mode 100644
index ..a29e14ee2efe
--- /dev/null
+++ b/include/dt-bindings/clock/mt7621-clk.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Weijie Gao 
+ */
+
+#ifndef __DT_BINDINGS_MT7621_CLK_H
+#define __DT_BINDINGS_MT7621_CLK_H
+
+#define MT7621_CLK_CPU 0
+#define MT7621_CLK_BUS 1
+
+#define MT7621_CLK_MAX 2
+
+#endif /* __DT_BINDINGS_MT7621_CLK_H */
-- 
2.21.0



[PATCH 0/5] MIPS: ralink: add CPU clock detection for MT7621

2019-07-09 Thread Chuanhong Guo
This patchset ports CPU clock detection for MT7621 from OpenWrt.

Last time I sent this, I forgot to add an binding include which
caused a compile error and the patch doesn't stay in linux-next.

This patchset resent the first two commits and also added binding
documentation for mt7621-pll and used it in mt7621-dts at
drivers/staging.

BTW: What should I do with such a patchset that touches multiple
parts in kernel?
Is it correct to send the entire patchset to lists of all involved
subsystems?

Chuanhong Guo (5):
  MIPS: ralink: add dt binding header for mt7621-pll
  MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices
  dt: bindings: add mt7621-pll dt binding documentation
  staging: mt7621-dts: add dt nodes for mt7621-pll
  staging: mt7621-dts: fix register range of memc node in mt7621.dtsi

 .../bindings/clock/mediatek,mt7621-pll.txt|  19 
 arch/mips/include/asm/mach-ralink/mt7621.h|  20 
 arch/mips/ralink/mt7621.c | 102 --
 arch/mips/ralink/timer-gic.c  |   4 +-
 drivers/staging/mt7621-dts/mt7621.dtsi|  17 ++-
 include/dt-bindings/clock/mt7621-clk.h|  14 +++
 6 files changed, 134 insertions(+), 42 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
 create mode 100644 include/dt-bindings/clock/mt7621-clk.h

-- 
2.21.0



[PATCH] MIPS: ralink: add mt7621-clk.h for device tree binding

2019-05-16 Thread Chuanhong Guo
This patch adds dt binding header for mediatek,mt7621-pll which
was added in:
commit e6046b5e69a0 ("MIPS: ralink: fix cpu clock of mt7621 and add dt clk 
devices")

Signed-off-by: Weijie Gao 
Signed-off-by: Chuanhong Guo 
---

checkpatch.pl shows a warning that the line referencing old commit
is over 75 chars but if I shink it down anyhow it gave me an error
saying I should use a proper style for commits. So I chose to ignore
the warning and fix the error.

 include/dt-bindings/clock/mt7621-clk.h | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt7621-clk.h

diff --git a/include/dt-bindings/clock/mt7621-clk.h 
b/include/dt-bindings/clock/mt7621-clk.h
new file mode 100644
index ..a29e14ee2efe
--- /dev/null
+++ b/include/dt-bindings/clock/mt7621-clk.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Weijie Gao 
+ */
+
+#ifndef __DT_BINDINGS_MT7621_CLK_H
+#define __DT_BINDINGS_MT7621_CLK_H
+
+#define MT7621_CLK_CPU 0
+#define MT7621_CLK_BUS 1
+
+#define MT7621_CLK_MAX 2
+
+#endif /* __DT_BINDINGS_MT7621_CLK_H */
-- 
2.21.0



Re: [PATCH] MT7621-SPI: spi-mt7621: Fix alignment and style problems Fixed Coding function and style issues

2019-04-04 Thread Chuanhong Guo
Hi!

On Fri, Apr 5, 2019 at 2:53 AM Nilesh Hase  wrote:
>
> Fix checkpatch issues: "CHECK: Alignment should match open parenthesis"
>
> Signed-off-by: Nilesh Hase 
> ---
>  drivers/staging/mt7621-spi/spi-mt7621.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c 
> b/drivers/staging/mt7621-spi/spi-mt7621.c
> index b509f9fe3346..6fa9876f5a92 100644
> --- a/drivers/staging/mt7621-spi/spi-mt7621.c
> +++ b/drivers/staging/mt7621-spi/spi-mt7621.c
FYI This file doesn't exist now. The driver has been moved into
drivers/spi by this commit:
cbd66c626e16 spi: mt7621: Move SPI driver out of staging

It's in linux-next-20190329 and later tags.
> @@ -303,7 +303,7 @@ static int mt7621_spi_setup(struct spi_device *spi)
> struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
>
> if ((spi->max_speed_hz == 0) ||
> -   (spi->max_speed_hz > (rs->sys_freq / 2)))
> +   (spi->max_speed_hz > (rs->sys_freq / 2)))
> spi->max_speed_hz = (rs->sys_freq / 2);
>
> if (spi->max_speed_hz < (rs->sys_freq / 4097)) {
> --
> 2.20.1
>
Regards,
 Chuanhong Guo


[PATCH v2] MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices

2019-03-21 Thread Chuanhong Guo
For a long time the mt7621 uses a fixed cpu clock which causes a problem
if the cpu frequency is not 880MHz.

This patch fixes the cpu clock calculation and adds the cpu/bus clkdev
which will be used in dts.

Signed-off-by: Weijie Gao 

Ported from OpenWrt:
c7ca224299 ramips: fix cpu clock of mt7621 and add dt clk devices

Signed-off-by: Chuanhong Guo 
---

Change since v1:
 Correctly fix the following checkpatch.pl warning:
 WARNING: Missing a blank line after declarations
 #137: FILE: arch/mips/ralink/mt7621.c:146:
 +  u32 xtal_clk, cpu_clk, bus_clk;
 +  const static u32 prediv_tbl[] = {0, 1, 2, 2};

 arch/mips/include/asm/mach-ralink/mt7621.h |  20 
 arch/mips/ralink/mt7621.c  | 102 ++---
 arch/mips/ralink/timer-gic.c   |   4 +-
 3 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h 
b/arch/mips/include/asm/mach-ralink/mt7621.h
index a672e06fa5fd..b8a8834164c8 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -19,6 +19,10 @@
 #define SYSC_REG_CHIP_REV  0x0c
 #define SYSC_REG_SYSTEM_CONFIG00x10
 #define SYSC_REG_SYSTEM_CONFIG10x14
+#define SYSC_REG_CLKCFG0   0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+
+#define MEMC_REG_CPU_PLL   0x648
 
 #define CHIP_REV_PKG_MASK  0x1
 #define CHIP_REV_PKG_SHIFT 16
@@ -26,6 +30,22 @@
 #define CHIP_REV_VER_SHIFT 8
 #define CHIP_REV_ECO_MASK  0xf
 
+#define XTAL_MODE_SEL_MASK 0x7
+#define XTAL_MODE_SEL_SHIFT6
+
+#define CPU_CLK_SEL_MASK   0x3
+#define CPU_CLK_SEL_SHIFT  30
+
+#define CUR_CPU_FDIV_MASK  0x1f
+#define CUR_CPU_FDIV_SHIFT 8
+#define CUR_CPU_FFRAC_MASK 0x1f
+#define CUR_CPU_FFRAC_SHIFT0
+
+#define CPU_PLL_PREDIV_MASK0x3
+#define CPU_PLL_PREDIV_SHIFT   12
+#define CPU_PLL_FBDIV_MASK 0x7f
+#define CPU_PLL_FBDIV_SHIFT4
+
 #define MT7621_DRAM_BASE0x0
 #define MT7621_DDR2_SIZE_MIN   32
 #define MT7621_DDR2_SIZE_MAX   256
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index d2718de60b9b..6828eefb0a85 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -9,22 +9,22 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "common.h"
 
-#define SYSC_REG_SYSCFG0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL(BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1 1
 #define MT7621_GPIO_MODE_I2C   2
 #define MT7621_GPIO_MODE_UART3_MASK0x3
@@ -110,49 +110,89 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
{ 0 }
 };
 
+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+   .clks = clks,
+   .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
panic("Cannot detect cpc address");
 }
 
+static struct clk *__init mt7621_add_sys_clkdev(
+   const char *id, unsigned long rate)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+   if (IS_ERR(clk))
+   panic("failed to allocate %s clock structure", id);
+
+   err = clk_register_clkdev(clk, id, NULL);
+   if (err)
+   panic("unable to register %s clock device", id);
+
+   return clk;
+}
+
 void __init ralink_clk_init(void)
 {
-   int cpu_fdiv = 0;
-   int cpu_ffrac = 0;
-   int fbdiv = 0;
-   u32 clk_sts, syscfg;
-   u8 clk_sel = 0, xtal_mode;
-   u32 cpu_clk;
+   const static u32 prediv_tbl[] = {0, 1, 2, 2};
+   u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+   u32 pll, prediv, fbdiv;
+   u32 xtal_clk, cpu_clk, bus_clk;
+
+   syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+   xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
 
-   if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-   clk_sel = 1;
+   clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+   clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+   curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+   ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+   ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+   if (xtal_sel <= 2)
+   xtal_clk = 20 * 1000 * 1000;
+   else if (xtal_sel <= 5)
+   xtal_clk = 40 * 1000 * 1000;
+   else
+   xtal_clk = 25 * 1000 * 1000;
 
switch (clk_sel) {
cas

[PATCH resend] MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices

2019-03-21 Thread Chuanhong Guo
For a long time the mt7621 uses a fixed cpu clock which causes a problem
if the cpu frequency is not 880MHz.

This patch fixes the cpu clock calculation and adds the cpu/bus clkdev
which will be used in dts.

Signed-off-by: Weijie Gao 

Ported from OpenWrt:
c7ca224299 ramips: fix cpu clock of mt7621 and add dt clk devices

Signed-off-by: Chuanhong Guo 
---

Resend due to incorrect patch subject.

 arch/mips/include/asm/mach-ralink/mt7621.h |  20 
 arch/mips/ralink/mt7621.c  | 102 ++---
 arch/mips/ralink/timer-gic.c   |   4 +-
 3 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h 
b/arch/mips/include/asm/mach-ralink/mt7621.h
index a672e06fa5fd..b8a8834164c8 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -19,6 +19,10 @@
 #define SYSC_REG_CHIP_REV  0x0c
 #define SYSC_REG_SYSTEM_CONFIG00x10
 #define SYSC_REG_SYSTEM_CONFIG10x14
+#define SYSC_REG_CLKCFG0   0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+
+#define MEMC_REG_CPU_PLL   0x648
 
 #define CHIP_REV_PKG_MASK  0x1
 #define CHIP_REV_PKG_SHIFT 16
@@ -26,6 +30,22 @@
 #define CHIP_REV_VER_SHIFT 8
 #define CHIP_REV_ECO_MASK  0xf
 
+#define XTAL_MODE_SEL_MASK 0x7
+#define XTAL_MODE_SEL_SHIFT6
+
+#define CPU_CLK_SEL_MASK   0x3
+#define CPU_CLK_SEL_SHIFT  30
+
+#define CUR_CPU_FDIV_MASK  0x1f
+#define CUR_CPU_FDIV_SHIFT 8
+#define CUR_CPU_FFRAC_MASK 0x1f
+#define CUR_CPU_FFRAC_SHIFT0
+
+#define CPU_PLL_PREDIV_MASK0x3
+#define CPU_PLL_PREDIV_SHIFT   12
+#define CPU_PLL_FBDIV_MASK 0x7f
+#define CPU_PLL_FBDIV_SHIFT4
+
 #define MT7621_DRAM_BASE0x0
 #define MT7621_DDR2_SIZE_MIN   32
 #define MT7621_DDR2_SIZE_MAX   256
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index d2718de60b9b..0b2845a4a036 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -9,22 +9,22 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "common.h"
 
-#define SYSC_REG_SYSCFG0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL(BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1 1
 #define MT7621_GPIO_MODE_I2C   2
 #define MT7621_GPIO_MODE_UART3_MASK0x3
@@ -110,49 +110,90 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
{ 0 }
 };
 
+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+   .clks = clks,
+   .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
panic("Cannot detect cpc address");
 }
 
+static struct clk *__init mt7621_add_sys_clkdev(
+   const char *id, unsigned long rate)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+   if (IS_ERR(clk))
+   panic("failed to allocate %s clock structure", id);
+
+   err = clk_register_clkdev(clk, id, NULL);
+   if (err)
+   panic("unable to register %s clock device", id);
+
+   return clk;
+}
+
 void __init ralink_clk_init(void)
 {
-   int cpu_fdiv = 0;
-   int cpu_ffrac = 0;
-   int fbdiv = 0;
-   u32 clk_sts, syscfg;
-   u8 clk_sel = 0, xtal_mode;
-   u32 cpu_clk;
+   u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+   u32 pll, prediv, fbdiv;
+   u32 xtal_clk, cpu_clk, bus_clk;
+
+   const static u32 prediv_tbl[] = {0, 1, 2, 2};
+
+   syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+   xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
 
-   if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-   clk_sel = 1;
+   clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+   clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+   curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+   ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+   ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+   if (xtal_sel <= 2)
+   xtal_clk = 20 * 1000 * 1000;
+   else if (xtal_sel <= 5)
+   xtal_clk = 40 * 1000 * 1000;
+   else
+   xtal_clk = 25 * 1000 * 1000;
 
switch (clk_sel) {
case 0:
-   clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-   cpu_fdiv = ((clk_sts >> 8) & 0x1F);
-   cpu_ffrac = (clk_sts & 0x1F);
-   cpu_clk = (500 *

[no subject]

2019-03-21 Thread Chuanhong Guo
Date: Thu, 21 Mar 2019 10:14:34 +0800
Subject: [PATCH] MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices

For a long time the mt7621 uses a fixed cpu clock which causes a problem
if the cpu frequency is not 880MHz.

This patch fixes the cpu clock calculation and adds the cpu/bus clkdev
which will be used in dts.

Signed-off-by: Weijie Gao 

Ported from OpenWrt:
c7ca224299 ramips: fix cpu clock of mt7621 and add dt clk devices

Signed-off-by: Chuanhong Guo 
---
 arch/mips/include/asm/mach-ralink/mt7621.h |  20 
 arch/mips/ralink/mt7621.c  | 102 ++---
 arch/mips/ralink/timer-gic.c   |   4 +-
 3 files changed, 93 insertions(+), 33 deletions(-)

diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h 
b/arch/mips/include/asm/mach-ralink/mt7621.h
index a672e06fa5fd..b8a8834164c8 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -19,6 +19,10 @@
 #define SYSC_REG_CHIP_REV  0x0c
 #define SYSC_REG_SYSTEM_CONFIG00x10
 #define SYSC_REG_SYSTEM_CONFIG10x14
+#define SYSC_REG_CLKCFG0   0x2c
+#define SYSC_REG_CUR_CLK_STS   0x44
+
+#define MEMC_REG_CPU_PLL   0x648
 
 #define CHIP_REV_PKG_MASK  0x1
 #define CHIP_REV_PKG_SHIFT 16
@@ -26,6 +30,22 @@
 #define CHIP_REV_VER_SHIFT 8
 #define CHIP_REV_ECO_MASK  0xf
 
+#define XTAL_MODE_SEL_MASK 0x7
+#define XTAL_MODE_SEL_SHIFT6
+
+#define CPU_CLK_SEL_MASK   0x3
+#define CPU_CLK_SEL_SHIFT  30
+
+#define CUR_CPU_FDIV_MASK  0x1f
+#define CUR_CPU_FDIV_SHIFT 8
+#define CUR_CPU_FFRAC_MASK 0x1f
+#define CUR_CPU_FFRAC_SHIFT0
+
+#define CPU_PLL_PREDIV_MASK0x3
+#define CPU_PLL_PREDIV_SHIFT   12
+#define CPU_PLL_FBDIV_MASK 0x7f
+#define CPU_PLL_FBDIV_SHIFT4
+
 #define MT7621_DRAM_BASE0x0
 #define MT7621_DDR2_SIZE_MIN   32
 #define MT7621_DDR2_SIZE_MAX   256
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index d2718de60b9b..0b2845a4a036 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -9,22 +9,22 @@
 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "common.h"
 
-#define SYSC_REG_SYSCFG0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL(BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1 1
 #define MT7621_GPIO_MODE_I2C   2
 #define MT7621_GPIO_MODE_UART3_MASK0x3
@@ -110,49 +110,90 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
{ 0 }
 };
 
+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+   .clks = clks,
+   .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
panic("Cannot detect cpc address");
 }
 
+static struct clk *__init mt7621_add_sys_clkdev(
+   const char *id, unsigned long rate)
+{
+   struct clk *clk;
+   int err;
+
+   clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+   if (IS_ERR(clk))
+   panic("failed to allocate %s clock structure", id);
+
+   err = clk_register_clkdev(clk, id, NULL);
+   if (err)
+   panic("unable to register %s clock device", id);
+
+   return clk;
+}
+
 void __init ralink_clk_init(void)
 {
-   int cpu_fdiv = 0;
-   int cpu_ffrac = 0;
-   int fbdiv = 0;
-   u32 clk_sts, syscfg;
-   u8 clk_sel = 0, xtal_mode;
-   u32 cpu_clk;
+   u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+   u32 pll, prediv, fbdiv;
+   u32 xtal_clk, cpu_clk, bus_clk;
+
+   const static u32 prediv_tbl[] = {0, 1, 2, 2};
+
+   syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+   xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
 
-   if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-   clk_sel = 1;
+   clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+   clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+   curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+   ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+   ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+   if (xtal_sel <= 2)
+   xtal_clk = 20 * 1000 * 1000;
+   else if (xtal_sel <= 5)
+   xtal_clk = 40 * 1000 * 1000;
+   else
+   xtal_clk = 25 * 1000 * 1000;
 
switch (clk_sel) {
case 0:
-   clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-   cpu_fdiv = ((clk_sts >> 8) & 0x1F);
- 

Re: [PATCH] spi: mediatek: Attempt to address style issues in spi-mt7621.c

2019-03-13 Thread Chuanhong Guo
Hi!
On Thu, Mar 14, 2019 at 6:14 AM NeilBrown  wrote:
>
> [...]
> My only small concern is that this driver was backported to openwrt
> (4.14 based) and then reverted
>
> https://github.com/openwrt/openwrt/commit/749a29f76ca780d8df70a5163d43bbdc6f13ba3f
>
>  "This breaks some mt7621 devices."
>
> Possibly it was backported badly, or possibly there is a problem.
Last time I backported the version with broken SPI modes so it got
broken SPI CS1 support. There is one mt7621 router using SPI CS1 in
OpenWrt and the backported driver broke it.
It has been fixed by my two "drop broken spi modes" patches.
>
> John: do you have any more details of the problem other than what is in
> the commit message?
>
> Thanks,
> NeilBrown

Regards,
Chuanhong Guo


Re: [PATCH] spi: mediatek: Attempt to address style issues in spi-mt7621.c

2019-03-13 Thread Chuanhong Guo
Hi!
On Wed, Mar 13, 2019 at 8:28 PM Matthias Brugger  wrote:
>
>
>
> On 13/03/2019 13:24, Armando Miraglia wrote:
> [...]
> Apart from fixing styling issues it would be usefull to see if we can add
> support for mt7621 to drivers/spi/spi-mt65xx.c
It's impossible. They are completely different IPs.
>
> Not sure if that is something you want to work on :)
>
> Regards,
> Matthias


Re: [PATCH] arm64: dts: meson-gxl-s905d-phicomm-n1: add status LED

2019-03-12 Thread Chuanhong Guo
Hi!
On Tue, Mar 12, 2019 at 4:59 PM Neil Armstrong  wrote:
> [...]
> BTW, do you know if it's possible to have a sample of the Phicomm N1
> in order to be added in kernelci ?
It's easy to purchase one in China and second-handed ones are dirt
cheap, but I don't think it's available worldwide.
I'm not familiar with world-wide shipping or exporting stuff so I
can't help much here.
>
> Neil


[PATCH] arm64: dts: meson-gxl-s905d-phicomm-n1: add status LED

2019-03-12 Thread Chuanhong Guo
There is a white LED on the front panel behind the logo and the
manufacturer uses that LED to indicate network and USB drive status.

Signed-off-by: Chuanhong Guo 
---
 .../boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts| 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
index 9a8a8a7e4b53..b5667f1fb2c8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts
@@ -14,6 +14,16 @@
cvbs-connector {
status = "disabled";
};
+
+   leds {
+   compatible = "gpio-leds";
+
+   status {
+   label = "n1:white:status";
+   gpios = <_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
+   default-state = "on";
+   };
+   };
 };
 
 _vdac_port {
-- 
2.20.1