Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v1 6/7] MAINTAINERS: update entry for PIN CONTROLLER - MEDIATEK
From: Linus Walleij @ 2018-05-24  7:41 UTC (permalink / raw)
  To: Sean Wang
  Cc: Rob Herring, Mark Rutland, Matthias Brugger,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Mediatek SoC support, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org
In-Reply-To: <e5bcfc9671a79fef4f38933bb04894f0f53b3d63.1526835466.git.sean.wang@mediatek.com>

On Sun, May 20, 2018 at 7:01 PM,  <sean.wang@mediatek.com> wrote:

> From: Sean Wang <sean.wang@mediatek.com>
>
> Add new files for the entry
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v1 7/7] arm64: dts: mt7622: add EINT support to pinctrl
From: Linus Walleij @ 2018-05-24  7:42 UTC (permalink / raw)
  To: Sean Wang
  Cc: Rob Herring, Mark Rutland, Matthias Brugger,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Mediatek SoC support, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org
In-Reply-To: <f896f79ebfa9a262c89fdeed89cf086220ca051d.1526835466.git.sean.wang@mediatek.com>

On Sun, May 20, 2018 at 7:01 PM,  <sean.wang@mediatek.com> wrote:

> From: Sean Wang <sean.wang@mediatek.com>
>
> Add EINT support to pinctrl and set those GPIO keys as interrupt-driven
> keys.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Please merge this through the ARM SoC tree.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [RESEND PATCH 2/5] mtd: rawnand: add NVIDIA Tegra NAND Flash controller driver
From: Benjamin Lindqvist @ 2018-05-24  7:45 UTC (permalink / raw)
  To: Stefan Agner
  Cc: boris.brezillon, dwmw2, computersforpeace, marek.vasut, robh+dt,
	mark.rutland, thierry.reding, mturquette, sboyd, Lucas Stach,
	miquel.raynal, richard, marcel, krzk, digetx, jonathanh,
	pdeschrijver, pgaikwad, Mirza Krak, linux-mtd, linux-tegra,
	devicetree, linux-kernel, linux-clk
In-Reply-To: <86fdf19ec92b732709732fb60199f16488b4b727.1526990589.git.stefan@agner.ch>

Hi Stefan (and all),

First off, I apoloigize in advance if I'm deviating from common
kernel mailing list courtesy -- this is my first time responding.
I just have a comment on the NAND driver that I'd like to bring
to the public.

> +       switch (mtd->oobsize) {
> ...
> +       case 224:
> +               mtd_set_ooblayout(mtd, &tegra_nand_oob_224_ops);
> +               chip->ecc.strength = 8;
> +               chip->ecc.bytes = 18;
> +               value |= CFG_ECC_SEL | CFG_TVAL_8;
> +               break; +       case 224:

I am not sure how you arrived at this oobsize-based inference. I
have not seen any explicit relation between oob size and ECC
algorithm used in the reference manual. Indeed, the U-Boot I was
working on (a fork of the Toradex 2015.04 U-Boot) always has
oobsize == 224 but used either BCH[t=16] or RS[t=4]. In fact, we
tried choosing RS[t=8] in U-Boot but we failed to make the
BootROM decode this at all. So we had to use RS[t=4]. But
changing the algorithm did not automatically change the oobsize,
at least it didn't for us. So maybe you should consider if this
is really the way to go about deciding which algorithm is used.

Note that we're in fact using this patch set in Linux today, but
we had to remove the oobsize inference part. Currently we're
simply hard coding it to CFG_TVAL_4, but maybe it would be
cleaner to add ECC algo as a board config instead, e.g. in the
.dts file or whatever. This seems to be done by other vendors
already, see for example excerpt of
Documentation/devicetree/bindings/mtd/gpmc-nand.txt below:

 - ti,nand-ecc-opt: A string setting the ECC layout to use. One of:
"sw" 1-bit Hamming ecc code via software
"hw" <deprecated> use "ham1" instead
"hw-romcode" <deprecated> use "ham1" instead
"ham1" 1-bit Hamming ecc code
"bch4" 4-bit BCH ecc code
"bch8" 8-bit BCH ecc code
"bch16" 16-bit BCH ECC code
Refer below "How to select correct ECC scheme for your device ?"

It seems as if this method would be equally applicable to Tegra NAND.

Best regards,
Benjamin

^ permalink raw reply

* Re: [PATCH v2 4/7] Bluetooth: Add new quirk for non-persistent setup settings
From: Marcel Holtmann @ 2018-05-24  7:47 UTC (permalink / raw)
  To: Sean Wang
  Cc: Mark Rutland, devicetree, Johan Hedberg, LKML, BlueZ development,
	Rob Herring, linux-mediatek, linux-arm-kernel
In-Reply-To: <1527084544.4607.8.camel@mtkswgap22>

Hi Sean,

>>>> 
>>>> [ ... ]
>>>> 
>>>>>> -	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
>>>>>> +	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
>>>>>> +	    test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
>>>>>> 		hci_sock_dev_event(hdev, HCI_DEV_SETUP);
>>>>> 
>>>>> I am not 100% sure that we want to send the HCI_DEV_SETUP event also multiple times. That is a userspace change that I would need to think about. We need to check create_monitor_event() and see what the btmon trace for this looks like. Can you send me a btmon -w trace.log when this change is active.
>>>>> 
>>>>> Regards
>>>>> 
>>>>> Marcel
>>>>> 
>>>> 
>>>> Sure, I'll send you the trace.log with the change is active.
>>>> 
>>>> 	Sean
>>>> 
>>> 
>>> 
>>> Attached trace.log was captured when I inputted commands power on and
>>> then off in bluetoothctl.
>> 
>> the trace.log is somehow mangled. Something is not fully correct. Can you read it with btmon -r trace.log?
>> 
>> Regards
>> 
>> Marcel
>> 
> 
> Yes, I can read it with btmon -r trace.log.
> 
> I post it as plain text as below 
> 
> 
> Bluetooth monitor ver 5.37
> = Note: Linux version 4.16.0-rc1+ (aarch64)                            0.641494
> = Note: Bluetooth subsystem version 2.22                               0.641502
> = New Index: 00:00:46:76:22:01 (BR/EDR,UART,hci0)               [hci0] 0.641505
> * Unknown packet (code 14 len 30)                                      0.641509
>        01 00 00 00 02 00 01 0e 00 01 00 00 00 10 62 6c  ..............bl
>        75 65 74 6f 6f 74 68 64 00 00 00 00 00 00        uetoothd......  
> * Unknown packet (code 14 len 30)                                      0.641592
>        02 00 00 00 02 00 01 0e 00 01 00 00 00 10 62 74  ..............bt
>        6d 6f 6e 00 00 00 00 00 00 00 00 00 00 00        mon...........  
> * Unknown packet (code 16 len 7)                                [hci0] 6.536771
>        01 00 00 00 05 00 01                             .......         
> = Open Index: 00:00:46:76:22:01                                 [hci0] 6.717019
> = Index Info: 00:00:46:76:22:01 (MediaTek, Inc.)                [hci0] 6.717030

can you try with the latest BlueZ 5.49 or git version. Seems it actually stumbles over the extra packet here. Fun fact is that I can not get a backtrace to pin-point the issue in btmon and why it crashes.

>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.741093
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.742088
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.743102
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.744105
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.745109
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.746104
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.747097
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.748090
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.749078
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.750070
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.751061
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.752054
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.753046
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.754038
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.755031
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.756025
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.757013
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.758006
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.758999
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.759991
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.760983
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.761975
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.762963
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.763956
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.764948
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.765941
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.766933
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.767926
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.768919
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.769914
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.770909
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.771908
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.772904
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.773898
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.774892
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.775890
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.776882
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.777877
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.778871
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.779869
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.780864
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.781858
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.782852
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.783850
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.784845
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.785839
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.786833
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.787831
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.788826
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.789820
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.790814
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.791813
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.792809
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.793803
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.794798
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.795797
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.796791
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.797786
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.798779
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.799778
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.800774
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.801769
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.802763
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.803761
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.804755
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.805749
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.806743
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.807741
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.808737
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.809731
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.810725
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.811725
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.812719
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.813714
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.814708
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.815705
>        02 01 01 00 00                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.816378
>        02 01 01 00 00                                   .....           

Why do I see only HCI events here? Is this event conveying any useful information. It is kinda complicated that this is 0xe4 event code which is actually reserved for future use by the Bluetooth SIG. Are there any accompanying HCI commands for this and they just not make it into btmon?

> < HCI Command: Vendor (0x3f|0x006f) plen 5                      [hci0] 6.816413
>        01 07 01 00 04                                   .....           
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 6.816536
>        02 07 01 00 00                                   .....           
> < HCI Command: Vendor (0x3f|0x006f) plen 6                      [hci0] 8.845071
>        01 06 02 00 00 01                                ......          
>> HCI Event: Unknown (0xe4) plen 5                              [hci0] 8.923456
>        02 06 01 00 00                                   .....           

Here it looks like you have 0x006f opcode with first octet 0x01 for command and then vendor event 0xe4 with first octet 0x02 for event. I assume the second octet is then the vendor command code for these.

> < HCI Command: Reset (0x03|0x0003) plen 0                      [hci0] 10.861118
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.865763
>      Reset (0x03|0x0003) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Local Supported Fe.. (0x04|0x0003) plen 0  [hci0] 10.865805
>> HCI Event: Command Complete (0x0e) plen 12                   [hci0] 10.865965
>      Read Local Supported Features (0x04|0x0003) ncmd 1
>        Status: Success (0x00)
>        Features: 0xbf 0x3e 0x8d 0xfe 0xdb 0xff 0x7b 0x87
>          3 slot packets
>          5 slot packets
>          Encryption
>          Slot offset
>          Timing accuracy
>          Role switch
>          Sniff mode
>          Power control requests
>          Channel quality driven data rate (CQDDR)
>          SCO link
>          HV2 packets
>          HV3 packets
>          CVSD synchronous data
>          Power control
>          Transparent synchronous data
>          Broadcast Encryption
>          Enhanced Data Rate ACL 2 Mbps mode
>          Enhanced Data Rate ACL 3 Mbps mode
>          Enhanced inquiry scan
>          Interlaced inquiry scan
>          Interlaced page scan
>          RSSI with inquiry results
>          Extended SCO link (EV3 packets)
>          EV4 packets
>          EV5 packets
>          AFH capable slave
>          AFH classification slave
>          LE Supported (Controller)
>          3-slot Enhanced Data Rate ACL packets
>          5-slot Enhanced Data Rate ACL packets
>          Sniff subrating
>          Pause encryption
>          AFH capable master
>          AFH classification master
>          Enhanced Data Rate eSCO 2 Mbps mode
>          Enhanced Data Rate eSCO 3 Mbps mode
>          3-slot Enhanced Data Rate eSCO packets
>          Extended Inquiry Response
>          Simultaneous LE and BR/EDR (Controller)
>          Secure Simple Pairing
>          Encapsulated PDU
>          Erroneous Data Reporting
>          Non-flushable Packet Boundary Flag
>          Link Supervision Timeout Changed Event
>          Inquiry TX Power Level
>          Enhanced Power Control
>          Extended features
> < HCI Command: Read Local Version Info.. (0x04|0x0001) plen 0  [hci0] 10.865987
>> HCI Event: Vendor (0xff) plen 9                              [hci0] 10.866259
>        29 19 09 17 20 48 07 11 00                       )... H…       

Is this meant to happen here?

>> HCI Event: Command Complete (0x0e) plen 12                   [hci0] 10.866372
>      Read Local Version Information (0x04|0x0001) ncmd 1
>        Status: Success (0x00)
>        HCI version: Bluetooth 4.2 (0x08) - Revision 4359 (0x1107)
>        LMP version: Bluetooth 4.2 (0x08) - Subversion 2329 (0x0919)
>        Manufacturer: MediaTek, Inc. (70)
> < HCI Command: Read BD ADDR (0x04|0x0009) plen 0               [hci0] 10.866391
>> HCI Event: Command Complete (0x0e) plen 10                   [hci0] 10.866539
>      Read BD ADDR (0x04|0x0009) ncmd 1
>        Status: Success (0x00)
>        Address: 00:00:46:76:22:01 (OLIVETTI NORTH AMERICA)
> < HCI Command: Read Buffer Size (0x04|0x0005) plen 0           [hci0] 10.866609
>> HCI Event: Command Complete (0x0e) plen 11                   [hci0] 10.866754
>      Read Buffer Size (0x04|0x0005) ncmd 1
>        Status: Success (0x00)
>        ACL MTU: 1021 ACL max packet: 8
>        SCO MTU: 184  SCO max packet: 1
> < HCI Command: Read Class of Device (0x03|0x0023) plen 0       [hci0] 10.866775
>> HCI Event: Command Complete (0x0e) plen 7                    [hci0] 10.866920
>      Read Class of Device (0x03|0x0023) ncmd 1
>        Status: Success (0x00)
>        Class: 0x001f00
>          Major class: Uncategorized, specific device code not specified
>          Minor class: 0x00
> < HCI Command: Read Local Name (0x03|0x0014) plen 0            [hci0] 10.866939
>> HCI Event: Command Complete (0x0e) plen 252                  [hci0] 10.867256
>      Read Local Name (0x03|0x0014) ncmd 1
>        Status: Success (0x00)
>        Name: MTK MT7622 #1
> < HCI Command: Read Voice Setting (0x03|0x0025) plen 0         [hci0] 10.867308
>> HCI Event: Command Complete (0x0e) plen 6                    [hci0] 10.867447
>      Read Voice Setting (0x03|0x0025) ncmd 1
>        Status: Success (0x00)
>        Setting: 0x0060
>          Input Coding: Linear
>          Input Data Format: 2's complement
>          Input Sample Size: 16-bit
>          # of bits padding at MSB: 0
>          Air Coding Format: CVSD
> < HCI Command: Read Number of Supporte.. (0x03|0x0038) plen 0  [hci0] 10.867474
>> HCI Event: Command Complete (0x0e) plen 5                    [hci0] 10.867611
>      Read Number of Supported IAC (0x03|0x0038) ncmd 1
>        Status: Success (0x00)
>        Number of IAC: 4
> < HCI Command: Read Current IAC LAP (0x03|0x0039) plen 0       [hci0] 10.867678
>> HCI Event: Command Complete (0x0e) plen 8                    [hci0] 10.867865
>      Read Current IAC LAP (0x03|0x0039) ncmd 1
>        Status: Success (0x00)
>        Number of IAC: 1
>        Access code: 0x9e8b33 (General Inquiry)
> < HCI Command: Set Event Filter (0x03|0x0005) plen 1           [hci0] 10.867890
>        Type: Clear All Filters (0x00)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.868033
>      Set Event Filter (0x03|0x0005) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write Connection Accept.. (0x03|0x0016) plen 2  [hci0] 10.868054
>        Timeout: 20000.000 msec (0x7d00)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.868235
>      Write Connection Accept Timeout (0x03|0x0016) ncmd 1
>        Status: Success (0x00)
> < HCI Command: LE Read Buffer Size (0x08|0x0002) plen 0        [hci0] 10.868262
>> HCI Event: Command Complete (0x0e) plen 7                    [hci0] 10.868392
>      LE Read Buffer Size (0x08|0x0002) ncmd 1
>        Status: Success (0x00)
>        Data packet length: 251
>        Num data packets: 8
> < HCI Command: LE Read Local Supported.. (0x08|0x0003) plen 0  [hci0] 10.868413
>> HCI Event: Command Complete (0x0e) plen 12                   [hci0] 10.868587
>      LE Read Local Supported Features (0x08|0x0003) ncmd 1
>        Status: Success (0x00)
>        Features: 0xfd 0x00 0x00 0x00 0x00 0x00 0x00 0x00
>          LE Encryption
>          Extended Reject Indication
>          Slave-initiated Features Exchange
>          LE Ping
>          LE Data Packet Length Extension
>          LL Privacy
>          Extended Scanner Filter Policies
> < HCI Command: LE Read Supported States (0x08|0x001c) plen 0   [hci0] 10.868646
>> HCI Event: Command Complete (0x0e) plen 12                   [hci0] 10.868787
>      LE Read Supported States (0x08|0x001c) ncmd 1
>        Status: Success (0x00)
>        States: 0x000000001fffffff
>          Non-connectable Advertising State
>          Scannable Advertising State
>          Connectable Advertising State
>          High Duty Cycle Directed Advertising State
>          Passive Scanning State
>          Active Scanning State
>          Initiating State
>            and Connection State (Master Role)
>          Connection State (Slave Role)
>          Non-connectable Advertising State
>            and Passive Scanning State
>          Scannable Advertising State
>            and Passive Scanning State
>          Connectable Advertising State
>            and Passive Scanning State
>          High Duty Cycle Directed Advertising State
>            and Passive Scanning State
>          Non-connectable Advertising State
>            and Active Scanning State
>          Scannable Advertising State
>            and Active Scanning State
>          Connectable Advertising State
>            and Active Scanning State
>          High Duty Cycle Directed Advertising State
>            and Active Scanning State
>          Non-connectable Advertising State
>            and Initiating State
>          Scannable Advertising State
>            and Initiating State
>          Non-connectable Advertising State
>            and Connection State (Master Role)
>          Scannable Advertising State
>            and Connection State (Master Role)
>          Non-connectable Advertising State
>            and Connection State (Slave Role)
>          Scannable Advertising State
>            and Connection State (Slave Role)
>          Passive Scanning State
>            and Initiating State
>          Active Scanning State
>            and Initiating State
>          Passive Scanning State
>            and Connection State (Master Role)
>          Active Scanning State
>            and Connection State (Master Role)
>          Passive Scanning State
>            and Connection State (Slave Role)
>          Active Scanning State
>            and Connection State (Slave Role)
>          Initiating State
>            and Connection State (Master Role)
>            and Master Role & Master Role
> < HCI Command: Read Local Supported Co.. (0x04|0x0002) plen 0  [hci0] 10.868807
>> HCI Event: Command Complete (0x0e) plen 68                   [hci0] 10.868985
>      Read Local Supported Commands (0x04|0x0002) ncmd 1
>        Status: Success (0x00)
>        Commands: 176 entries
>          Inquiry (Octet 0 - Bit 0)
>          Inquiry Cancel (Octet 0 - Bit 1)
>          Periodic Inquiry Mode (Octet 0 - Bit 2)
>          Exit Periodic Inquiry Mode (Octet 0 - Bit 3)
>          Create Connection (Octet 0 - Bit 4)
>          Disconnect (Octet 0 - Bit 5)
>          Add SCO Connection (Octet 0 - Bit 6)
>          Create Connection Cancel (Octet 0 - Bit 7)
>          Accept Connection Request (Octet 1 - Bit 0)
>          Reject Connection Request (Octet 1 - Bit 1)
>          Link Key Request Reply (Octet 1 - Bit 2)
>          Link Key Request Negative Reply (Octet 1 - Bit 3)
>          PIN Code Request Reply (Octet 1 - Bit 4)
>          PIN Code Request Negative Reply (Octet 1 - Bit 5)
>          Change Connection Packet Type (Octet 1 - Bit 6)
>          Authentication Requested (Octet 1 - Bit 7)
>          Set Connection Encryption (Octet 2 - Bit 0)
>          Change Connection Link Key (Octet 2 - Bit 1)
>          Master Link Key (Octet 2 - Bit 2)
>          Remote Name Request (Octet 2 - Bit 3)
>          Remote Name Request Cancel (Octet 2 - Bit 4)
>          Read Remote Supported Features (Octet 2 - Bit 5)
>          Read Remote Extended Features (Octet 2 - Bit 6)
>          Read Remote Version Information (Octet 2 - Bit 7)
>          Read Clock Offset (Octet 3 - Bit 0)
>          Read LMP Handle (Octet 3 - Bit 1)
>          Sniff Mode (Octet 4 - Bit 2)
>          Exit Sniff Mode (Octet 4 - Bit 3)
>          QoS Setup (Octet 4 - Bit 6)
>          Role Discovery (Octet 4 - Bit 7)
>          Switch Role (Octet 5 - Bit 0)
>          Read Link Policy Settings (Octet 5 - Bit 1)
>          Write Link Policy Settings (Octet 5 - Bit 2)
>          Read Default Link Policy Settings (Octet 5 - Bit 3)
>          Write Default Link Policy Settings (Octet 5 - Bit 4)
>          Flow Specification (Octet 5 - Bit 5)
>          Set Event Mask (Octet 5 - Bit 6)
>          Reset (Octet 5 - Bit 7)
>          Set Event Filter (Octet 6 - Bit 0)
>          Flush (Octet 6 - Bit 1)
>          Read PIN Type (Octet 6 - Bit 2)
>          Write PIN Type (Octet 6 - Bit 3)
>          Create New Unit Key (Octet 6 - Bit 4)
>          Read Stored Link Key (Octet 6 - Bit 5)
>          Write Stored Link Key (Octet 6 - Bit 6)
>          Delete Stored Link Key (Octet 6 - Bit 7)
>          Write Local Name (Octet 7 - Bit 0)
>          Read Local Name (Octet 7 - Bit 1)
>          Read Connection Accept Timeout (Octet 7 - Bit 2)
>          Write Connection Accept Timeout (Octet 7 - Bit 3)
>          Read Page Timeout (Octet 7 - Bit 4)
>          Write Page Timeout (Octet 7 - Bit 5)
>          Read Scan Enable (Octet 7 - Bit 6)
>          Write Scan Enable (Octet 7 - Bit 7)
>          Read Page Scan Activity (Octet 8 - Bit 0)
>          Write Page Scan Activity (Octet 8 - Bit 1)
>          Read Inquiry Scan Activity (Octet 8 - Bit 2)
>          Write Inquiry Scan Activity (Octet 8 - Bit 3)
>          Read Authentication Enable (Octet 8 - Bit 4)
>          Write Authentication Enable (Octet 8 - Bit 5)
>          Read Encryption Mode (Octet 8 - Bit 6)
>          Write Encryption Mode (Octet 8 - Bit 7)
>          Read Class of Device (Octet 9 - Bit 0)
>          Write Class of Device (Octet 9 - Bit 1)
>          Read Voice Setting (Octet 9 - Bit 2)
>          Write Voice Setting (Octet 9 - Bit 3)
>          Read Automatic Flush Timeout (Octet 9 - Bit 4)
>          Write Automatic Flush Timeout (Octet 9 - Bit 5)
>          Read Num Broadcast Retransmissions (Octet 9 - Bit 6)
>          Write Num Broadcast Retransmissions (Octet 9 - Bit 7)
>          Read Transmit Power Level (Octet 10 - Bit 2)
>          Read Sync Flow Control Enable (Octet 10 - Bit 3)
>          Write Sync Flow Control Enable (Octet 10 - Bit 4)
>          Set Controller To Host Flow Control (Octet 10 - Bit 5)
>          Host Buffer Size (Octet 10 - Bit 6)
>          Host Number of Completed Packets (Octet 10 - Bit 7)
>          Read Link Supervision Timeout (Octet 11 - Bit 0)
>          Write Link Supervision Timeout (Octet 11 - Bit 1)
>          Read Number of Supported IAC (Octet 11 - Bit 2)
>          Read Current IAC LAP (Octet 11 - Bit 3)
>          Write Current IAC LAP (Octet 11 - Bit 4)
>          Read Page Scan Mode (Octet 11 - Bit 7)
>          Write Page Scan Mode (Octet 12 - Bit 0)
>          Set AFH Host Channel Classification (Octet 12 - Bit 1)
>          Read Inquiry Scan Type (Octet 12 - Bit 4)
>          Write Inquiry Scan Type (Octet 12 - Bit 5)
>          Read Inquiry Mode (Octet 12 - Bit 6)
>          Write Inquiry Mode (Octet 12 - Bit 7)
>          Read Page Scan Type (Octet 13 - Bit 0)
>          Write Page Scan Type (Octet 13 - Bit 1)
>          Read AFH Channel Assessment Mode (Octet 13 - Bit 2)
>          Write AFH Channel Assessment Mode (Octet 13 - Bit 3)
>          Read Local Version Information (Octet 14 - Bit 3)
>          Read Local Supported Features (Octet 14 - Bit 5)
>          Read Local Extended Features (Octet 14 - Bit 6)
>          Read Buffer Size (Octet 14 - Bit 7)
>          Read Country Code (Octet 15 - Bit 0)
>          Read BD ADDR (Octet 15 - Bit 1)
>          Read Failed Contact Counter (Octet 15 - Bit 2)
>          Reset Failed Contact Counter (Octet 15 - Bit 3)
>          Read Link Quality (Octet 15 - Bit 4)
>          Read RSSI (Octet 15 - Bit 5)
>          Read AFH Channel Map (Octet 15 - Bit 6)
>          Read Clock (Octet 15 - Bit 7)
>          Read Loopback Mode (Octet 16 - Bit 0)
>          Write Loopback Mode (Octet 16 - Bit 1)
>          Enable Device Under Test Mode (Octet 16 - Bit 2)
>          Setup Synchronous Connection (Octet 16 - Bit 3)
>          Accept Synchronous Connection Request (Octet 16 - Bit 4)
>          Reject Synchronous Connection Request (Octet 16 - Bit 5)
>          Read Extended Inquiry Response (Octet 17 - Bit 0)
>          Write Extended Inquiry Response (Octet 17 - Bit 1)
>          Refresh Encryption Key (Octet 17 - Bit 2)
>          Sniff Subrating (Octet 17 - Bit 4)
>          Read Simple Pairing Mode (Octet 17 - Bit 5)
>          Write Simple Pairing Mode (Octet 17 - Bit 6)
>          Read Local OOB Data (Octet 17 - Bit 7)
>          Read Inquiry Response TX Power Level (Octet 18 - Bit 0)
>          Write Inquiry Transmit Power Level (Octet 18 - Bit 1)
>          Read Default Erroneous Data Reporting (Octet 18 - Bit 2)
>          Write Default Erroneous Data Reporting (Octet 18 - Bit 3)
>          IO Capability Request Reply (Octet 18 - Bit 7)
>          User Confirmation Request Reply (Octet 19 - Bit 0)
>          User Confirmation Request Neg Reply (Octet 19 - Bit 1)
>          User Passkey Request Reply (Octet 19 - Bit 2)
>          User Passkey Request Negative Reply (Octet 19 - Bit 3)
>          Remote OOB Data Request Reply (Octet 19 - Bit 4)
>          Write Simple Pairing Debug Mode (Octet 19 - Bit 5)
>          Enhanced Flush (Octet 19 - Bit 6)
>          Remote OOB Data Request Neg Reply (Octet 19 - Bit 7)
>          Send Keypress Notification (Octet 20 - Bit 2)
>          IO Capability Request Negative Reply (Octet 20 - Bit 3)
>          Read Encryption Key Size (Octet 20 - Bit 4)
>          Set Event Mask Page 2 (Octet 22 - Bit 2)
>          Read Enhanced Transmit Power Level (Octet 24 - Bit 0)
>          Enhanced Setup Synchronous Connection (Octet 29 - Bit 3)
>          Enhanced Accept Synchronous Connection Request (Octet 29 - Bit 4)
>          Read Local Supported Codecs (Octet 29 - Bit 5)
>          Set Triggered Clock Capture (Octet 30 - Bit 5)
>          Truncated Page (Octet 30 - Bit 6)
>          Truncated Page Cancel (Octet 30 - Bit 7)
>          Set Connectionless Slave Broadcast (Octet 31 - Bit 0)
>          Start Synchronization Train (Octet 31 - Bit 2)
>          Set Reserved LT_ADDR (Octet 31 - Bit 4)
>          Delete Reserved LT_ADDR (Octet 31 - Bit 5)
>          Set Connectionless Slave Broadcast Data (Octet 31 - Bit 6)
>          Read Synchronization Train Parameters (Octet 31 - Bit 7)
>          Write Synchronization Train Parameters (Octet 32 - Bit 0)
>          Remote OOB Extended Data Request Reply (Octet 32 - Bit 1)
>          Read Authenticated Payload Timeout (Octet 32 - Bit 4)
>          Write Authenticated Payload Timeout (Octet 32 - Bit 5)
>          Read Local OOB Extended Data (Octet 32 - Bit 6)
>          Write Secure Connections Test Mode (Octet 32 - Bit 7)
>          Read Extended Page Timeout (Octet 33 - Bit 0)
>          Write Extended Page Timeout (Octet 33 - Bit 1)
>          Read Extended Inquiry Length (Octet 33 - Bit 2)
>          Write Extended Inquiry Length (Octet 33 - Bit 3)
>          LE Set Data Length (Octet 33 - Bit 6)
>          LE Read Suggested Default Data Length (Octet 33 - Bit 7)
>          LE Write Suggested Default Data Length (Octet 34 - Bit 0)
>          LE Read Local P-256 Public Key (Octet 34 - Bit 1)
>          LE Generate DHKey (Octet 34 - Bit 2)
>          LE Add Device To Resolving List (Octet 34 - Bit 3)
>          LE Remove Device From Resolving List (Octet 34 - Bit 4)
>          LE Clear Resolving List (Octet 34 - Bit 5)
>          LE Read Resolving List Size (Octet 34 - Bit 6)
>          LE Read Peer Resolvable Address (Octet 34 - Bit 7)
>          LE Read Local Resolvable Address (Octet 35 - Bit 0)
>          LE Set Address Resolution Enable (Octet 35 - Bit 1)
>          LE Set Resolvable Private Address Timeout (Octet 35 - Bit 2)
>          LE Read Maximum Data Length (Octet 35 - Bit 3)
>          Octet 35 - Bit 4 
>          Octet 35 - Bit 5 
>          Octet 35 - Bit 6 
>          Octet 35 - Bit 7 
>          Octet 36 - Bit 0 

So you support the PHY commands, but do not indicate support LE 2M or LE Coded? Also these are Bluetooth 5.0 commands.

> < HCI Command: Write Simple Pairing Mode (0x03|0x0056) plen 1  [hci0] 10.869023
>        Mode: Enabled (0x01)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.869185
>      Write Simple Pairing Mode (0x03|0x0056) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write Inquiry Mode (0x03|0x0045) plen 1         [hci0] 10.869239
>        Mode: Inquiry Result with RSSI or Extended Inquiry Result (0x02)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.869371
>      Write Inquiry Mode (0x03|0x0045) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Inquiry Response T.. (0x03|0x0058) plen 0  [hci0] 10.869396
>> HCI Event: Command Complete (0x0e) plen 5                    [hci0] 10.869552
>      Read Inquiry Response TX Power Level (0x03|0x0058) ncmd 1
>        Status: Success (0x00)
>        TX power: -1 dBm
> < HCI Command: Read Local Extended Fea.. (0x04|0x0004) plen 1  [hci0] 10.869572
>        Page: 1
>> HCI Event: Command Complete (0x0e) plen 14                   [hci0] 10.869729
>      Read Local Extended Features (0x04|0x0004) ncmd 1
>        Status: Success (0x00)
>        Page: 1/2
>        Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
>          Secure Simple Pairing (Host Support)
> < HCI Command: Set Event Mask (0x03|0x0001) plen 8             [hci0] 10.869783
>        Mask: 0x3dbff807fffbffff
>          Inquiry Complete
>          Inquiry Result
>          Connection Complete
>          Connection Request
>          Disconnection Complete
>          Authentication Complete
>          Remote Name Request Complete
>          Encryption Change
>          Change Connection Link Key Complete
>          Master Link Key Complete
>          Read Remote Supported Features Complete
>          Read Remote Version Information Complete
>          QoS Setup Complete
>          Command Complete
>          Command Status
>          Hardware Error
>          Flush Occurred
>          Role Change
>          Mode Change
>          Return Link Keys
>          PIN Code Request
>          Link Key Request
>          Link Key Notification
>          Loopback Command
>          Data Buffer Overflow
>          Max Slots Change
>          Read Clock Offset Complete
>          Connection Packet Type Changed
>          QoS Violation
>          Page Scan Mode Change
>          Page Scan Repetition Mode Change
>          Flow Specification Complete
>          Inquiry Result with RSSI
>          Read Remote Extended Features Complete
>          Synchronous Connection Complete
>          Synchronous Connection Changed
>          Sniff Subrating
>          Extended Inquiry Result
>          Encryption Key Refresh Complete
>          IO Capability Request
>          IO Capability Request Reply
>          User Confirmation Request
>          User Passkey Request
>          Remote OOB Data Request
>          Simple Pairing Complete
>          Link Supervision Timeout Changed
>          Enhanced Flush Complete
>          User Passkey Notification
>          Keypress Notification
>          Remote Host Supported Features Notification
>          LE Meta
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.869921
>      Set Event Mask (0x03|0x0001) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Stored Link Key (0x03|0x000d) plen 7       [hci0] 10.869947
>        Address: 00:00:00:00:00:00 (OUI 00-00-00)
>        Read all: 0x01
>> HCI Event: Command Complete (0x0e) plen 8                    [hci0] 10.870129
>      Read Stored Link Key (0x03|0x000d) ncmd 1
>        Status: Success (0x00)
>        Max num keys: 4
>        Num keys: 0
> < HCI Command: Write Default Link Poli.. (0x02|0x000f) plen 2  [hci0] 10.870148
>        Link policy: 0x0005
>          Enable Role Switch
>          Enable Sniff Mode
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.870310
>      Write Default Link Policy Settings (0x02|0x000f) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Page Scan Activity (0x03|0x001b) plen 0    [hci0] 10.870331
>> HCI Event: Command Complete (0x0e) plen 8                    [hci0] 10.870485
>      Read Page Scan Activity (0x03|0x001b) ncmd 1
>        Status: Success (0x00)
>        Interval: 1280.000 msec (0x0800)
>        Window: 11.250 msec (0x0012)
> < HCI Command: Read Page Scan Type (0x03|0x0046) plen 0        [hci0] 10.870504
>> HCI Event: Command Complete (0x0e) plen 5                    [hci0] 10.870652
>      Read Page Scan Type (0x03|0x0046) ncmd 1
>        Status: Success (0x00)
>        Type: Standard Scan (0x00)
> < HCI Command: LE Set Event Mask (0x08|0x0001) plen 8          [hci0] 10.870671
>        Mask: 0x0000000000000980
>          LE Read Local P-256 Public Key Complete
>          LE Generate DHKey Complete
>          Unknown mask (0x0000000000000800)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.870839
>      LE Set Event Mask (0x08|0x0001) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write LE Host Supported (0x03|0x006d) plen 2    [hci0] 10.870859
>        Supported: 0x01
>        Simultaneous: 0x00
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.871028
>      Write LE Host Supported (0x03|0x006d) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Local Extended Fea.. (0x04|0x0004) plen 1  [hci0] 10.871059
>        Page: 2
>> HCI Event: Command Complete (0x0e) plen 14                   [hci0] 10.871201
>      Read Local Extended Features (0x04|0x0004) ncmd 1
>        Status: Success (0x00)
>        Page: 2/2
>        Features: 0x25 0x0b 0x00 0x00 0x00 0x00 0x00 0x00
>          Connectionless Slave Broadcast - Master
>          Synchronization Train
>          Generalized interlaced scan
>          Secure Connections (Controller Support)
>          Ping
>          Train nudging
> < HCI Command: Delete Stored Link Key (0x03|0x0012) plen 7     [hci0] 10.871240
>        Address: 00:00:00:00:00:00 (OUI 00-00-00)
>        Delete all: 0x01
>> HCI Event: Command Complete (0x0e) plen 6                    [hci0] 10.871384
>      Delete Stored Link Key (0x03|0x0012) ncmd 1
>        Status: Success (0x00)
>        Num keys: 0
> < HCI Command: Set Event Mask Page 2 (0x03|0x0063) plen 8      [hci0] 10.871403
>        Mask: 0x0000000000b0c000
>          Triggered Clock Capture
>          Synchronization Train Complete
>          Slave Page Response Timeout
>          Connectionless Slave Broadcast Channel Map Change
>          Authenticated Payload Timeout Expired
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.871566
>      Set Event Mask Page 2 (0x03|0x0063) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Read Local Supported Co.. (0x04|0x000b) plen 0  [hci0] 10.871599
>> HCI Event: Command Complete (0x0e) plen 8                    [hci0] 10.871750
>      Read Local Supported Codecs (0x04|0x000b) ncmd 1
>        Status: Success (0x00)
>        Number of supported codecs: 2
>          Codec: CVSD (0x02)
>          Codec: Transparent (0x03)
>        Number of vendor codecs: 0
> < HCI Command: Read Synchronization Tr.. (0x03|0x0077) plen 0  [hci0] 10.871769
>> HCI Event: Command Complete (0x0e) plen 11                   [hci0] 10.871928
>      Read Synchronization Train Parameters (0x03|0x0077) ncmd 1
>        Status: Success (0x00)
>        Interval: 0.000 msec (0x0000)
>        Timeout: 0.000 msec (0x00000000)
>        Service data: 0x00
> < HCI Command: Write Secure Connection.. (0x03|0x007a) plen 1  [hci0] 10.871947
>        Support: Enabled (0x01)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.872098
>      Write Secure Connections Host Support (0x03|0x007a) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Unknown (0x08|0x0031) plen 3                    [hci0] 10.872156
>        03 00 00                                         ...             
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.872322
>      Unknown (0x08|0x0031) ncmd 1
>        Status: Success (0x00)
> = Index Info: 00:00:46:76:22:01 (MediaTek, Inc.)               [hci0] 10.872361

This extra index info worries me a little bit. I need to check if that is suppose to happen.

> < HCI Command: LE Set Scan Response D.. (0x08|0x0009) plen 32  [hci0] 10.872431
>        Length: 10
>        Name (complete): builder
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.872606
>      LE Set Scan Response Data (0x08|0x0009) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write Scan Enable (0x03|0x001a) plen 1          [hci0] 10.872627
>        Scan enable: Page Scan (0x02)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.872819
>      Write Scan Enable (0x03|0x001a) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write Class of Device (0x03|0x0024) plen 3      [hci0] 10.872841
>        Class: 0x000000
>          Major class: Miscellaneous
>          Minor class: 0x00
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.873036
>      Write Class of Device (0x03|0x0024) ncmd 1
>        Status: Success (0x00)
> * Unknown packet (code 17 len 9)                               [hci0] 10.873069
>        02 00 00 00 07 00 00 00 00                       .........       
> * Unknown packet (code 17 len 9)                               [hci0] 10.873069
>        01 00 00 00 07 00 00 00 00                       .........       
> < HCI Command: Write Local Name (0x03|0x0013) plen 248         [hci0] 10.873096
>        Name: builder
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.873446
>      Write Local Name (0x03|0x0013) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Write Extended Inquir.. (0x03|0x0052) plen 241  [hci0] 10.873470
>        FEC: Not required (0x00)
>        Name (complete): builder
>        TX power: -1 dBm
>        Device ID: USB Implementer's Forum assigned (0x0002)
>          Vendor: Linux Foundation (0x1d6b)
>          Product: 0x0246
>          Version: 5.2.11 (0x052b)
>        16-bit Service UUIDs (complete): 4 entries
>          Generic Access Profile (0x1800)
>          Generic Attribute Profile (0x1801)
>          A/V Remote Control (0x110e)
>          A/V Remote Control Target (0x110c)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 10.873857
>      Write Extended Inquiry Response (0x03|0x0052) ncmd 1
>        Status: Success (0x00)
> * Unknown packet (code 17 len 13)                              [hci0] 10.873903
>        01 00 00 00 01 00 05 00 00 d1 0a 00 00           .............   
> * Unknown packet (code 17 len 10)                              [hci0] 10.873913
>        02 00 00 00 06 00 d1 0a 00 00                    ..........      
> * Unknown packet (code 16 len 7)                               [hci0] 17.803939
>        01 00 00 00 05 00 00                             .......         
> < HCI Command: Write Scan Enable (0x03|0x001a) plen 1          [hci0] 17.803983
>        Scan enable: No Scans (0x00)
>> HCI Event: Command Complete (0x0e) plen 4                    [hci0] 17.804233
>      Write Scan Enable (0x03|0x001a) ncmd 1
>        Status: Success (0x00)
> < HCI Command: Vendor (0x3f|0x006f) plen 6                     [hci0] 17.804282
>        01 06 02 00 00 00                                ......          
>> HCI Event: Unknown (0xe4) plen 5                             [hci0] 17.804636
>        02 06 01 00 00                                   .....           
> * Unknown packet (code 17 len 13)                              [hci0] 17.811580
>        01 00 00 00 01 00 05 00 00 d0 0a 00 00           .............   
> * Unknown packet (code 17 len 10)                              [hci0] 17.811596
>        02 00 00 00 06 00 d0 0a 00 00                    ..........      
> = Close Index: 00:00:46:76:22:01                               [hci0] 17.811625

Regards

Marcel

^ permalink raw reply

* [PATCH v12 0/8] Clock for CPU scaling support for msm8996
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin

[v12]
 * Addressed the kbuild fail on arm architecture

[v11]
 * Split the series into domains

[v9]
 * Addressed comments from Viresh and Russel about the error handling

[v8]
 * Reordered the patch series into 4 groups
 * Addressed comments from Amit about the comments and commit messages
 * Addressed comments from Amit and Viresh about the resourses deallocation

[v7]
 * Addressed comments from Viresh about resourses deallocation
   and DT compatible

[v6]
 * Addressed comments from Viresh about:
 ** Comments style
 ** Kconfig bool instead of tristate
 ** DT and documentation style
 ** Resourses deallocation on an error
 ** Typos

[v5]
 * Rebased
 * Addressed comments from Bjorn about SPDX style,
   functions and parameters naming
 * Addressed comments from Viresh DT properties and style, comments style,
   resourses deallocation, documentation placement
 * Addressed comments from Sricharan about unnessesary include
 * Addressed comments from Nicolas
 * Addressed comments from Rob about the commit messages and acks
 * Addressed comments from Mark

[v4]
 * Adressed all comments from Stephen
 * Added CPU regulator support
 * Added qcom-cpufreq-kryo driver

[v3]
 * Rebased on top of the latest PLL driver changes
 * Addressed comment from Rob Herring for bindings

[v2]
 * Addressed comments from Rob Herring for bindings
 * Addressed comments from Mark Rutland for memory barrier
 * Addressed comments from Julien Thierry for clock reenabling condition
 * Tuned the HW configuration for clock frequencies below 600MHz

SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver

Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.

Ilia Lin (6):
  soc: qcom: Separate kryo l2 accessors from PMU driver
  clk: Use devm_ in the register fixed factor clock
  clk: qcom: Add CPU clock driver for msm8996
  dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
  clk: qcom: cpu-8996: Add support to switch below 600Mhz
  clk: qcom: Add ACD path to CPU clock driver for msm8996

Rajendra Nayak (2):
  clk: qcom: Make clk_alpha_pll_configure available to modules
  clk: qcom: cpu-8996: Add support to switch to alternate PLL

 .../devicetree/bindings/clock/qcom,kryocc.txt      |  17 +
 drivers/clk/clk-fixed-factor.c                     |   2 +-
 drivers/clk/qcom/Kconfig                           |  10 +
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/clk-alpha-pll.c                   |   1 +
 drivers/clk/qcom/clk-alpha-pll.h                   |   6 +
 drivers/clk/qcom/clk-cpu-8996.c                    | 510 +++++++++++++++++++++
 drivers/perf/Kconfig                               |   1 +
 drivers/perf/qcom_l2_pmu.c                         |  90 +---
 drivers/soc/qcom/Kconfig                           |   3 +
 drivers/soc/qcom/Makefile                          |   1 +
 drivers/soc/qcom/kryo-l2-accessors.c               |  56 +++
 include/soc/qcom/kryo-l2-accessors.h               |  12 +
 13 files changed, 643 insertions(+), 67 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

-- 
1.9.1

^ permalink raw reply

* [PATCH v12 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/perf/Kconfig                 |  1 +
 drivers/perf/qcom_l2_pmu.c           | 90 ++++++++++--------------------------
 drivers/soc/qcom/Kconfig             |  3 ++
 drivers/soc/qcom/Makefile            |  1 +
 drivers/soc/qcom/kryo-l2-accessors.c | 56 ++++++++++++++++++++++
 include/soc/qcom/kryo-l2-accessors.h | 12 +++++
 6 files changed, 97 insertions(+), 66 deletions(-)
 create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
 create mode 100644 include/soc/qcom/kryo-l2-accessors.h

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
 config QCOM_L2_PMU
 	bool "Qualcomm Technologies L2-cache PMU"
 	depends on ARCH_QCOM && ARM64 && ACPI
+	select QCOM_KRYO_L2_ACCESSORS
 	  help
 	  Provides support for the L2 cache performance monitor unit (PMU)
 	  in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
 #include <asm/barrier.h>
 #include <asm/local64.h>
 #include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
 
 #define MAX_L2_CTRS             9
 
@@ -87,8 +88,6 @@
 #define L2_COUNTER_RELOAD       BIT_ULL(31)
 #define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
 
-#define L2CPUSRSELR_EL1         sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1           sys_reg(3, 3, 15, 0, 7)
 
 #define reg_idx(reg, i)         (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
 
@@ -107,48 +106,7 @@
 #define L2_EVENT_STREX                     0x421
 #define L2_EVENT_CLREX                     0x422
 
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
 
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&l2_access_lock, flags);
-	write_sysreg_s(reg, L2CPUSRSELR_EL1);
-	isb();
-	write_sysreg_s(val, L2CPUSRDR_EL1);
-	isb();
-	raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
-	u64 val;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&l2_access_lock, flags);
-	write_sysreg_s(reg, L2CPUSRSELR_EL1);
-	isb();
-	val = read_sysreg_s(L2CPUSRDR_EL1);
-	raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-
-	return val;
-}
 
 struct cluster_pmu;
 
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
 static void cluster_pmu_reset(void)
 {
 	/* Reset all counters */
-	set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
-	set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
-	set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
-	set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+	kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+	kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+	kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+	kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
 }
 
 static inline void cluster_pmu_enable(void)
 {
-	set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+	kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
 }
 
 static inline void cluster_pmu_disable(void)
 {
-	set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+	kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
 }
 
 static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
 {
 	if (idx == l2_cycle_ctr_idx)
-		set_l2_indirect_reg(L2PMCCNTR, value);
+		kryo_l2_set_indirect_reg(L2PMCCNTR, value);
 	else
-		set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+		kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
 }
 
 static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
 	u64 value;
 
 	if (idx == l2_cycle_ctr_idx)
-		value = get_l2_indirect_reg(L2PMCCNTR);
+		value = kryo_l2_get_indirect_reg(L2PMCCNTR);
 	else
-		value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+		value = kryo_l2_get_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
 
 	return value;
 }
 
 static inline void cluster_pmu_counter_enable(u32 idx)
 {
-	set_l2_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
+	kryo_l2_set_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
 }
 
 static inline void cluster_pmu_counter_disable(u32 idx)
 {
-	set_l2_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
+	kryo_l2_set_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
 }
 
 static inline void cluster_pmu_counter_enable_interrupt(u32 idx)
 {
-	set_l2_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
+	kryo_l2_set_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
 }
 
 static inline void cluster_pmu_counter_disable_interrupt(u32 idx)
 {
-	set_l2_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
+	kryo_l2_set_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
 }
 
 static inline void cluster_pmu_set_evccntcr(u32 val)
 {
-	set_l2_indirect_reg(L2PMCCNTCR, val);
+	kryo_l2_set_indirect_reg(L2PMCCNTCR, val);
 }
 
 static inline void cluster_pmu_set_evcntcr(u32 ctr, u32 val)
 {
-	set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
+	kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
 }
 
 static inline void cluster_pmu_set_evtyper(u32 ctr, u32 val)
 {
-	set_l2_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
+	kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
 }
 
 static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
@@ -303,11 +261,11 @@ static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
 
 	spin_lock_irqsave(&cluster->pmu_lock, flags);
 
-	resr_val = get_l2_indirect_reg(L2PMRESR);
+	resr_val = kryo_l2_get_indirect_reg(L2PMRESR);
 	resr_val &= ~(L2PMRESR_GROUP_MASK << shift);
 	resr_val |= field;
 	resr_val |= L2PMRESR_EN;
-	set_l2_indirect_reg(L2PMRESR, resr_val);
+	kryo_l2_set_indirect_reg(L2PMRESR, resr_val);
 
 	spin_unlock_irqrestore(&cluster->pmu_lock, flags);
 }
@@ -323,14 +281,14 @@ static inline void cluster_pmu_set_evfilter_sys_mode(u32 ctr)
 		   L2PMXEVFILTER_ORGFILTER_IDINDEP |
 		   L2PMXEVFILTER_ORGFILTER_ALL;
 
-	set_l2_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
+	kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
 }
 
 static inline u32 cluster_pmu_getreset_ovsr(void)
 {
-	u32 result = get_l2_indirect_reg(L2PMOVSSET);
+	u32 result = kryo_l2_get_indirect_reg(L2PMOVSSET);
 
-	set_l2_indirect_reg(L2PMOVSCLR, result);
+	kryo_l2_set_indirect_reg(L2PMOVSCLR, result);
 	return result;
 }
 
@@ -783,7 +741,7 @@ static int get_num_counters(void)
 {
 	int val;
 
-	val = get_l2_indirect_reg(L2PMCR);
+	val = kryo_l2_get_indirect_reg(L2PMCR);
 
 	/*
 	 * Read number of counters from L2PMCR and add 1
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 7093fe7..0567dff 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -39,6 +39,9 @@ config QCOM_GSBI
           functions for connecting the underlying serial UART, SPI, and I2C
           devices to the output pins.
 
+config QCOM_KRYO_L2_ACCESSORS
+       bool
+
 config QCOM_MDT_LOADER
 	tristate
 	select QCOM_SCM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index cbf414c..e4d3f5a 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=	kryo-l2-accessors.o
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
new file mode 100644
index 0000000..75fd07a
--- /dev/null
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/spinlock.h>
+#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
+
+#define L2CPUSRSELR_EL1         sys_reg(3, 3, 15, 0, 6)
+#define L2CPUSRDR_EL1           sys_reg(3, 3, 15, 0, 7)
+
+static DEFINE_RAW_SPINLOCK(l2_access_lock);
+
+/**
+ * kryo_l2_set_indirect_reg() - write value to an L2 register
+ * @reg: Address of L2 register.
+ * @value: Value to be written to register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+void kryo_l2_set_indirect_reg(u64 reg, u64 val)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2_access_lock, flags);
+	write_sysreg_s(reg, L2CPUSRSELR_EL1);
+	isb();
+	write_sysreg_s(val, L2CPUSRDR_EL1);
+	isb();
+	raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+}
+EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
+
+/**
+ * kryo_l2_get_indirect_reg() - read an L2 register value
+ * @reg: Address of L2 register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+u64 kryo_l2_get_indirect_reg(u64 reg)
+{
+	u64 val;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2_access_lock, flags);
+	write_sysreg_s(reg, L2CPUSRSELR_EL1);
+	isb();
+	val = read_sysreg_s(L2CPUSRDR_EL1);
+	raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+
+	return val;
+}
+EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
diff --git a/include/soc/qcom/kryo-l2-accessors.h b/include/soc/qcom/kryo-l2-accessors.h
new file mode 100644
index 0000000..673c534
--- /dev/null
+++ b/include/soc/qcom/kryo-l2-accessors.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+#define __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+
+void kryo_l2_set_indirect_reg(u64 reg, u64 val);
+u64 kryo_l2_get_indirect_reg(u64 reg);
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin, Rajendra Nayak
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

From: Rajendra Nayak <rnayak@codeaurora.org>

Allow clk_alpha_pll_configure to be called from loadable
kernel modules.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9722b70..57f2084 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	if (pll->flags & SUPPORTS_FSM_MODE)
 		qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 3/8] clk: Use devm_ in the register fixed factor clock
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/clk-fixed-factor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402d..8e39bda 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
 	init.num_parents = 1;
 
 	hw = &fix->hw;
-	ret = clk_hw_register(dev, hw);
+	ret = devm_clk_hw_register(dev, hw);
 	if (ret) {
 		kfree(fix);
 		hw = ERR_PTR(ret);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 4/8] clk: qcom: Add CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin, Rajendra Nayak
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

                             +-------+
              XO             |       |
          +------------------>0      |
                             |       |
                   PLL/2     | SMUX  +----+
                     +------->1      |    |
                     |       |       |    |
                     |       +-------+    |    +-------+
                     |                    +---->0      |
                     |                         |       |
+---------------+    |             +----------->1      | CPU clk
|Primary PLL    +----+ PLL_EARLY   |           |       +------>
|               +------+-----------+    +------>2 PMUX |
+---------------+      |                |      |       |
                       |   +------+     |   +-->3      |
                       +--^+  ACD +-----+   |  +-------+
+---------------+          +------+         |
|Alt PLL        |                           |
|               +---------------------------+
+---------------+         PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.

ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/qcom/Kconfig         |  10 +
 drivers/clk/qcom/Makefile        |   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 420 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-cpu-8996.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..42e84b5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
 	  Say Y if you want to support CPU frequency scaling on devices
 	  such as msm8916.
 
+config QCOM_CLK_APCC_MSM8996
+	tristate "MSM8996 CPU Clock Controller"
+	depends on ARM64
+	depends on COMMON_CLK_QCOM
+	select QCOM_KRYO_L2_ACCESSORS
+	help
+	  Support for the CPU clock controller on msm8996 devices.
+	  Say Y if you want to support CPU clock scaling using CPUfreq
+	  drivers for dyanmic power management.
+
 config QCOM_CLK_RPM
 	tristate "RPM based Clock Controller"
 	depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7c09ab1..a822fc8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..9ce2a32 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
 	u32 val;
 };
 
+#define VCO(a, b, c) { \
+	.val = a,\
+	.min_freq = b,\
+	.max_freq = c,\
+}
+
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 0000000..d92cad93
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ *                              +-------+
+ *               XO             |       |
+ *           +------------------>0      |
+ *                              |       |
+ *                    PLL/2     | SMUX  +----+
+ *                      +------->1      |    |
+ *                      |       |       |    |
+ *                      |       +-------+    |    +-------+
+ *                      |                    +---->0      |
+ *                      |                         |       |
+ * +---------------+    |             +----------->1      | CPU clk
+ * |Primary PLL    +----+ PLL_EARLY   |           |       +------>
+ * |               +------+-----------+    +------>2 PMUX |
+ * +---------------+      |                |      |       |
+ *                        |   +------+     |   +-->3      |
+ *                        +--^+  ACD +-----+   |  +-------+
+ * +---------------+          +------+         |
+ * |Alt PLL        |                           |
+ * |               +---------------------------+
+ * +---------------+         PLL_EARLY
+ *
+ * The primary PLL is what drives the CPU clk, except for times
+ * when we are reprogramming the PLL itself (for rate changes) when
+ * we temporarily switch to an alternate PLL. A subsequent patch adds
+ * support to switch between primary and alternate PLL during rate
+ * changes.
+ *
+ * The primary PLL operates on a single VCO range, between 600MHz
+ * and 3GHz. However the CPUs do support OPPs with frequencies
+ * between 300MHz and 600MHz. In order to support running the CPUs
+ * at those frequencies we end up having to lock the PLL at twice
+ * the rate and drive the CPU clk via the PLL/2 output and SMUX.
+ *
+ * So for frequencies above 600MHz we follow the following path
+ *  Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
+ * and for frequencies between 300MHz and 600MHz we follow
+ *  Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
+ * Support for this is added in a subsequent patch as well.
+ *
+ * ACD stands for Adaptive Clock Distribution and is used to
+ * detect voltage droops.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-regmap.h"
+
+enum _pmux_input {
+	DIV_2_INDEX = 0,
+	PLL_INDEX,
+	ACD_INDEX,
+	ALT_INDEX,
+	NUM_OF_PMUX_INPUTS
+};
+
+static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
+       [PLL_OFF_L_VAL] = 0x04,
+       [PLL_OFF_ALPHA_VAL] = 0x08,
+       [PLL_OFF_USER_CTL] = 0x10,
+       [PLL_OFF_CONFIG_CTL] = 0x18,
+       [PLL_OFF_CONFIG_CTL_U] = 0x1c,
+       [PLL_OFF_TEST_CTL] = 0x20,
+       [PLL_OFF_TEST_CTL_U] = 0x24,
+       [PLL_OFF_STATUS] = 0x28,
+};
+
+static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
+       [PLL_OFF_L_VAL] = 0x04,
+       [PLL_OFF_ALPHA_VAL] = 0x08,
+       [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+       [PLL_OFF_USER_CTL] = 0x10,
+       [PLL_OFF_USER_CTL_U] = 0x14,
+       [PLL_OFF_CONFIG_CTL] = 0x18,
+       [PLL_OFF_TEST_CTL] = 0x20,
+       [PLL_OFF_TEST_CTL_U] = 0x24,
+       [PLL_OFF_STATUS] = 0x28,
+};
+
+/* PLLs */
+
+static const struct alpha_pll_config hfpll_config = {
+	.l = 60,
+	.config_ctl_val = 0x200d4828,
+	.config_ctl_hi_val = 0x006,
+	.pre_div_mask = BIT(12),
+	.post_div_mask = 0x3 << 8,
+	.main_output_mask = BIT(0),
+	.early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_pll = {
+	.offset = 0x80000,
+	.regs = prim_pll_regs,
+	.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "perfcl_pll",
+		.parent_names = (const char *[]){ "xo" },
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_huayra_ops,
+	},
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+	.offset = 0x0,
+	.regs = prim_pll_regs,
+	.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "pwrcl_pll",
+		.parent_names = (const char *[]){ "xo" },
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_huayra_ops,
+	},
+};
+
+static const struct pll_vco alt_pll_vco_modes[] = {
+	VCO(3,  250000000,  500000000),
+	VCO(2,  500000000,  750000000),
+	VCO(1,  750000000, 1000000000),
+	VCO(0, 1000000000, 2150400000),
+};
+
+static const struct alpha_pll_config altpll_config = {
+	.l = 16,
+	.vco_val = 0x3 << 20,
+	.vco_mask = 0x3 << 20,
+	.config_ctl_val = 0x4001051b,
+	.post_div_mask = 0x3 << 8,
+	.post_div_val = 0x1,
+	.main_output_mask = BIT(0),
+	.early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_alt_pll = {
+	.offset = 0x80100,
+	.regs = alt_pll_regs,
+	.vco_table = alt_pll_vco_modes,
+	.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+	.flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "perfcl_alt_pll",
+		.parent_names = (const char *[]){ "xo" },
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_hwfsm_ops,
+	},
+};
+
+static struct clk_alpha_pll pwrcl_alt_pll = {
+	.offset = 0x100,
+	.regs = alt_pll_regs,
+	.vco_table = alt_pll_vco_modes,
+	.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+	.flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "pwrcl_alt_pll",
+		.parent_names = (const char *[]){ "xo" },
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_hwfsm_ops,
+	},
+};
+
+/* Mux'es */
+
+struct clk_cpu_8996_mux {
+	u32	reg;
+	u8	shift;
+	u8	width;
+	struct clk_hw	*pll;
+	struct clk_regmap clkr;
+};
+
+static inline
+struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+{
+	return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+}
+
+static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+{
+	u32 val;
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+	u32 mask = (u32)GENMASK(cpuclk->width - 1, 0);
+
+	regmap_read(clkr->regmap, cpuclk->reg, &val);
+	val >>= (u32)(cpuclk->shift);
+
+	return (u8)(val & mask);
+}
+
+static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	u32 val;
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+	unsigned int mask = GENMASK(cpuclk->width + cpuclk->shift - 1,
+				    cpuclk->shift);
+
+	val = (u32)index;
+	val <<= (u32)(cpuclk->shift);
+
+	return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+}
+
+static int
+clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+	struct clk_hw *parent = cpuclk->pll;
+
+	req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
+	req->best_parent_hw = parent;
+
+	return 0;
+}
+
+const struct clk_ops clk_cpu_8996_mux_ops = {
+	.set_parent = clk_cpu_8996_mux_set_parent,
+	.get_parent = clk_cpu_8996_mux_get_parent,
+	.determine_rate = clk_cpu_8996_mux_determine_rate,
+};
+
+static struct clk_cpu_8996_mux pwrcl_smux = {
+	.reg = 0x40,
+	.shift = 2,
+	.width = 2,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "pwrcl_smux",
+		.parent_names = (const char *[]){
+			"xo",
+			"pwrcl_pll_main",
+		},
+		.num_parents = 2,
+		.ops = &clk_cpu_8996_mux_ops,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_cpu_8996_mux perfcl_smux = {
+	.reg = 0x80040,
+	.shift = 2,
+	.width = 2,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "perfcl_smux",
+		.parent_names = (const char *[]){
+			"xo",
+			"perfcl_pll_main",
+		},
+		.num_parents = 2,
+		.ops = &clk_cpu_8996_mux_ops,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_cpu_8996_mux pwrcl_pmux = {
+	.reg = 0x40,
+	.shift = 0,
+	.width = 2,
+	.pll = &pwrcl_pll.clkr.hw,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "pwrcl_pmux",
+		.parent_names = (const char *[]){
+			"pwrcl_smux",
+			"pwrcl_pll",
+			"pwrcl_pll_acd",
+			"pwrcl_alt_pll",
+		},
+		.num_parents = 4,
+		.ops = &clk_cpu_8996_mux_ops,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_cpu_8996_mux perfcl_pmux = {
+	.reg = 0x80040,
+	.shift = 0,
+	.width = 2,
+	.pll = &perfcl_pll.clkr.hw,
+	.clkr.hw.init = &(struct clk_init_data) {
+		.name = "perfcl_pmux",
+		.parent_names = (const char *[]){
+			"perfcl_smux",
+			"perfcl_pll",
+			"perfcl_pll_acd",
+			"perfcl_alt_pll",
+		},
+		.num_parents = 4,
+		.ops = &clk_cpu_8996_mux_ops,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static const struct regmap_config cpu_msm8996_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= 0x80210,
+	.fast_io		= true,
+	.val_format_endian	= REGMAP_ENDIAN_LITTLE,
+};
+
+struct clk_regmap *clks[] = {
+	&perfcl_pll.clkr,
+	&pwrcl_pll.clkr,
+	&perfcl_alt_pll.clkr,
+	&pwrcl_alt_pll.clkr,
+	&perfcl_smux.clkr,
+	&pwrcl_smux.clkr,
+	&perfcl_pmux.clkr,
+	&pwrcl_pmux.clkr,
+};
+
+static int
+qcom_cpu_clk_msm8996_register_clks(struct device *dev, struct regmap *regmap)
+{
+	int i, ret;
+
+	perfcl_smux.pll = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
+						       "perfcl_pll",
+						   CLK_SET_RATE_PARENT, 1, 2);
+
+	pwrcl_smux.pll = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
+						      "pwrcl_pll",
+						   CLK_SET_RATE_PARENT, 1, 2);
+
+	for (i = 0; i < ARRAY_SIZE(clks); i++) {
+		ret = devm_clk_register_regmap(dev, clks[i]);
+		if (ret)
+			return ret;
+	}
+
+	clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
+	clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
+	clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+	clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+
+	return ret;
+}
+
+static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
+{
+	int ret;
+	void __iomem *base;
+	struct resource *res;
+	struct regmap *regmap;
+	struct clk_hw_onecell_data *data;
+	struct device *dev = &pdev->dev;
+
+	data = devm_kzalloc(dev, sizeof(*data) + 2 * sizeof(struct clk_hw *),
+			    GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	regmap = devm_regmap_init_mmio(dev, base, &cpu_msm8996_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = qcom_cpu_clk_msm8996_register_clks(dev, regmap);
+	if (ret)
+		return ret;
+
+	data->hws[0] = &pwrcl_pmux.clkr.hw;
+	data->hws[1] = &perfcl_pmux.clkr.hw;
+	data->num = 2;
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
+}
+
+static const struct of_device_id qcom_cpu_clk_msm8996_match_table[] = {
+	{ .compatible = "qcom,msm8996-apcc" },
+	{}
+};
+
+static struct platform_driver qcom_cpu_clk_msm8996_driver = {
+	.probe = qcom_cpu_clk_msm8996_driver_probe,
+	.driver = {
+		.name = "qcom-msm8996-apcc",
+		.of_match_table = qcom_cpu_clk_msm8996_match_table,
+	},
+};
+module_platform_driver(qcom_cpu_clk_msm8996_driver);
+
+MODULE_ALIAS("platform:msm8996-apcc");
+MODULE_DESCRIPTION("QCOM MSM8996 CPU Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below

                             +-------+
              XO             |       |
          +------------------>0      |
                             |       |
                   PLL/2     | SMUX  +----+
                     +------->1      |    |
                     |       |       |    |
                     |       +-------+    |    +-------+
                     |                    +---->0      |
                     |                         |       |
+---------------+    |             +----------->1      | CPU clk
|Primary PLL    +----+ PLL_EARLY   |           |       +------>
|               +------+-----------+    +------>2 PMUX |
+---------------+      |                |      |       |
                       |   +------+     |   +-->3      |
                       +--^+  ACD +-----+   |  +-------+
+---------------+          +------+         |
|Alt PLL        |                           |
|               +---------------------------+
+---------------+         PLL_EARLY

The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.

The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt

diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 0000000..8458783
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+----------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+			"qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+	kryocc: clock-controller@6400000 {
+		compatible = "qcom,msm8996-apcc";
+		reg = <0x6400000 0x90000>;
+		#clock-cells = <1>;
+	};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin, Rajendra Nayak
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

From: Rajendra Nayak <rnayak@codeaurora.org>

Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/qcom/clk-cpu-8996.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93..620fdc2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
  * detect voltage droops.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
 	u32	reg;
 	u8	shift;
 	u8	width;
+	struct notifier_block nb;
 	struct clk_hw	*pll;
 	struct clk_regmap clkr;
 };
 
+#define to_clk_cpu_8996_mux_nb(_nb) \
+	container_of(_nb, struct clk_cpu_8996_mux, nb)
+
 static inline
 struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
 {
@@ -227,6 +232,26 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
 	return 0;
 }
 
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+			void *data)
+{
+	int ret;
+	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+	switch (event) {
+	case PRE_RATE_CHANGE:
+		ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+		break;
+	case POST_RATE_CHANGE:
+		ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+
+	return notifier_from_errno(ret);
+};
 const struct clk_ops clk_cpu_8996_mux_ops = {
 	.set_parent = clk_cpu_8996_mux_set_parent,
 	.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
 	.shift = 0,
 	.width = 2,
 	.pll = &pwrcl_pll.clkr.hw,
+	.nb.notifier_call = cpu_clk_notifier_cb,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "pwrcl_pmux",
 		.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
 	.shift = 0,
 	.width = 2,
 	.pll = &perfcl_pll.clkr.hw,
+	.nb.notifier_call = cpu_clk_notifier_cb,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "perfcl_pmux",
 		.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ struct clk_regmap *clks[] = {
 	clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
 	clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
 
+	ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+	if (ret)
+		return ret;
+
+	ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+
 	return ret;
 }
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin, Rajendra Nayak
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.

So for frequencies above 600MHz we follow the following path
 Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
 Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/qcom/clk-cpu-8996.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2..ff5c0a5 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
 	NUM_OF_PMUX_INPUTS
 };
 
+#define DIV_2_THRESHOLD		600000000
+
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
        [PLL_OFF_L_VAL] = 0x04,
        [PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ enum _pmux_input {
 
 static const struct alpha_pll_config hfpll_config = {
 	.l = 60,
-	.config_ctl_val = 0x200d4828,
+	.config_ctl_val = 0x200d4aa8,
 	.config_ctl_hi_val = 0x006,
 	.pre_div_mask = BIT(12),
 	.post_div_mask = 0x3 << 8,
+	.post_div_val = 0x1 << 8,
 	.main_output_mask = BIT(0),
 	.early_output_mask = BIT(3),
 };
@@ -140,7 +143,7 @@ enum _pmux_input {
 	.vco_mask = 0x3 << 20,
 	.config_ctl_val = 0x4001051b,
 	.post_div_mask = 0x3 << 8,
-	.post_div_val = 0x1,
+	.post_div_val = 0x1 << 8,
 	.main_output_mask = BIT(0),
 	.early_output_mask = BIT(3),
 };
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
 	u8	width;
 	struct notifier_block nb;
 	struct clk_hw	*pll;
+	struct clk_hw	*pll_div_2;
 	struct clk_regmap clkr;
 };
 
@@ -226,6 +230,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
 	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
 	struct clk_hw *parent = cpuclk->pll;
 
+	if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+		if (req->rate < (DIV_2_THRESHOLD / 2))
+			return -EINVAL;
+
+		parent = cpuclk->pll_div_2;
+	}
+
 	req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
 	req->best_parent_hw = parent;
 
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 {
 	int ret;
 	struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+	struct clk_notifier_data *cnd = data;
 
 	switch (event) {
 	case PRE_RATE_CHANGE:
 		ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
 		break;
 	case POST_RATE_CHANGE:
-		ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+		if (cnd->new_rate < DIV_2_THRESHOLD)
+			ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+							  DIV_2_INDEX);
+		else
+			ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+							  PLL_INDEX);
 		break;
 	default:
 		ret = 0;
@@ -295,6 +312,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 	.shift = 0,
 	.width = 2,
 	.pll = &pwrcl_pll.clkr.hw,
+	.pll_div_2 = &pwrcl_smux.clkr.hw,
 	.nb.notifier_call = cpu_clk_notifier_cb,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 	.shift = 0,
 	.width = 2,
 	.pll = &perfcl_pll.clkr.hw,
+	.pll_div_2 = &perfcl_smux.clkr.hw,
 	.nb.notifier_call = cpu_clk_notifier_cb,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "perfcl_pmux",
-- 
1.9.1

^ permalink raw reply related

* [PATCH v12 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-24  7:50 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-msm, linux-soc,
	linux-arm-kernel, vireshk, ilialin
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>

The PMUX for each duplex allows for selection of ACD clock source.
The DVM (Dynamic Variation Monitor) will flag an error
when a voltage droop event is detected. This flagged error
enables ACD to provide a div-by-2 clock, sourced from the primary PLL.
The duplex will be provided the divided clock
until a pre-programmed delay has expired.

This change configures ACD during the probe and switches
the PMUXes to the ACD clock source.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
 drivers/clk/qcom/clk-cpu-8996.c | 75 +++++++++++++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index ff5c0a5..0a908d8 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -53,9 +53,11 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <soc/qcom/kryo-l2-accessors.h>
 
 #include "clk-alpha-pll.h"
 #include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
 };
 
 #define DIV_2_THRESHOLD		600000000
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x80000
+#define MUX_OFFSET	0x40
+#define ALT_PLL_OFFSET	0x100
+#define SSSCTL_OFFSET 0x160
 
 static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
        [PLL_OFF_L_VAL] = 0x04,
@@ -107,7 +114,7 @@ enum _pmux_input {
 };
 
 static struct clk_alpha_pll perfcl_pll = {
-	.offset = 0x80000,
+	.offset = PERFCL_REG_OFFSET,
 	.regs = prim_pll_regs,
 	.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
 	.clkr.hw.init = &(struct clk_init_data){
@@ -119,7 +126,7 @@ enum _pmux_input {
 };
 
 static struct clk_alpha_pll pwrcl_pll = {
-	.offset = 0x0,
+	.offset = PWRCL_REG_OFFSET,
 	.regs = prim_pll_regs,
 	.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
 	.clkr.hw.init = &(struct clk_init_data){
@@ -149,7 +156,7 @@ enum _pmux_input {
 };
 
 static struct clk_alpha_pll perfcl_alt_pll = {
-	.offset = 0x80100,
+	.offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
 	.regs = alt_pll_regs,
 	.vco_table = alt_pll_vco_modes,
 	.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -163,7 +170,7 @@ enum _pmux_input {
 };
 
 static struct clk_alpha_pll pwrcl_alt_pll = {
-	.offset = 0x100,
+	.offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
 	.regs = alt_pll_regs,
 	.vco_table = alt_pll_vco_modes,
 	.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -176,6 +183,9 @@ enum _pmux_input {
 	},
 };
 
+void __iomem *base;
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base);
+
 /* Mux'es */
 
 struct clk_cpu_8996_mux {
@@ -253,6 +263,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 	switch (event) {
 	case PRE_RATE_CHANGE:
 		ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+		qcom_cpu_clk_msm8996_acd_init(base);
 		break;
 	case POST_RATE_CHANGE:
 		if (cnd->new_rate < DIV_2_THRESHOLD)
@@ -260,7 +271,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 							  DIV_2_INDEX);
 		else
 			ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
-							  PLL_INDEX);
+							  ACD_INDEX);
 		break;
 	default:
 		ret = 0;
@@ -276,7 +287,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 };
 
 static struct clk_cpu_8996_mux pwrcl_smux = {
-	.reg = 0x40,
+	.reg = PWRCL_REG_OFFSET + MUX_OFFSET,
 	.shift = 2,
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data) {
@@ -292,7 +303,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 };
 
 static struct clk_cpu_8996_mux perfcl_smux = {
-	.reg = 0x80040,
+	.reg = PERFCL_REG_OFFSET + MUX_OFFSET,
 	.shift = 2,
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data) {
@@ -308,7 +319,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 };
 
 static struct clk_cpu_8996_mux pwrcl_pmux = {
-	.reg = 0x40,
+	.reg = PWRCL_REG_OFFSET + MUX_OFFSET,
 	.shift = 0,
 	.width = 2,
 	.pll = &pwrcl_pll.clkr.hw,
@@ -329,7 +340,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 };
 
 static struct clk_cpu_8996_mux perfcl_pmux = {
-	.reg = 0x80040,
+	.reg = PERFCL_REG_OFFSET + MUX_OFFSET,
 	.shift = 0,
 	.width = 2,
 	.pll = &perfcl_pll.clkr.hw,
@@ -393,6 +404,10 @@ struct clk_regmap *clks[] = {
 	clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
 	clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
 
+	/* Enable alt PLLs */
+	clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+	clk_prepare_enable(perfcl_alt_pll.clkr.hw.clk);
+
 	ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
 	if (ret)
 		return ret;
@@ -402,10 +417,48 @@ struct clk_regmap *clks[] = {
 	return ret;
 }
 
+#define CPU_AFINITY_MASK 0xFFF
+#define PWRCL_CPU_REG_MASK 0x3
+#define PERFCL_CPU_REG_MASK 0x103
+
+#define L2ACDCR_REG 0x580ULL
+#define L2ACDTD_REG 0x581ULL
+#define L2ACDDVMRC_REG 0x584ULL
+#define L2ACDSSCR_REG 0x589ULL
+
+static DEFINE_SPINLOCK(acd_lock);
+
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base)
+{
+	u64 hwid;
+	unsigned long flags;
+
+	spin_lock_irqsave(&acd_lock, flags);
+
+	hwid = read_cpuid_mpidr() & CPU_AFINITY_MASK;
+
+	kryo_l2_set_indirect_reg(L2ACDTD_REG, 0x00006A11);
+	kryo_l2_set_indirect_reg(L2ACDDVMRC_REG, 0x000E0F0F);
+	kryo_l2_set_indirect_reg(L2ACDSSCR_REG, 0x00000601);
+
+	if (PWRCL_CPU_REG_MASK == (hwid | PWRCL_CPU_REG_MASK)) {
+		writel(0xF, base + PWRCL_REG_OFFSET + SSSCTL_OFFSET);
+		wmb();
+		kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+	}
+
+	if (PERFCL_CPU_REG_MASK == (hwid | PERFCL_CPU_REG_MASK)) {
+		kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+		writel(0xF, base + PERFCL_REG_OFFSET + SSSCTL_OFFSET);
+		wmb();
+	}
+
+	spin_unlock_irqrestore(&acd_lock, flags);
+}
+
 static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
 {
 	int ret;
-	void __iomem *base;
 	struct resource *res;
 	struct regmap *regmap;
 	struct clk_hw_onecell_data *data;
@@ -429,6 +482,8 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	qcom_cpu_clk_msm8996_acd_init(base);
+
 	data->hws[0] = &pwrcl_pmux.clkr.hw;
 	data->hws[1] = &perfcl_pmux.clkr.hw;
 	data->num = 2;
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v5 2/4] pinctrl: msm: fix gpio-hog related boot issues
From: Linus Walleij @ 2018-05-24  8:04 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	David Brown, Stephen Boyd, linux-arm-msm, Bjorn Andersson,
	open list:GPIO SUBSYSTEM, Rob Herring, Sven Eckelmann, Andy Gross,
	Linux ARM
In-Reply-To: <270904bcbf03a6b6ac3150f4a7daa15aa7e97586.1526935804.git.chunkeey@gmail.com>

On Mon, May 21, 2018 at 10:57 PM, Christian Lamparter
<chunkeey@gmail.com> wrote:

> Sven Eckelmann reported an issue with the current IPQ4019 pinctrl.
> Setting up any gpio-hog in the device-tree for his device would
> "kill the bootup completely":
>
> | [    0.477838] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe
> | [    0.499828] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferring probe
> | [    1.298883] requesting hog GPIO enable USB2 power (chip 1000000.pinctrl, offset 58) failed, -517
> | [    1.299609] gpiochip_add_data: GPIOs 0..99 (1000000.pinctrl) failed to register
> | [    1.308589] ipq4019-pinctrl 1000000.pinctrl: Failed register gpiochip
> | [    1.316586] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe
> | [    1.322415] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferri
>
> This was also verified on a RT-AC58U (IPQ4018) which would
> no longer boot, if a gpio-hog was specified. (Tried forcing
> the USB LED PIN (GPIO0) to high.).
>
> The problem is that Pinctrl+GPIO registration is currently
> peformed in the following order in pinctrl-msm.c:
>         1. pinctrl_register()
>         2. gpiochip_add()
>         3. gpiochip_add_pin_range()
>
> The actual error code -517 == -EPROBE_DEFER is coming from
> pinctrl_get_device_gpio_range(), which is called through:
>         gpiochip_add
>             of_gpiochip_add
>                 of_gpiochip_scan_gpios
>                     gpiod_hog
>                         gpiochip_request_own_desc
>                             __gpiod_request
>                                 chip->request
>                                     gpiochip_generic_request
>                                        pinctrl_gpio_request
>                                           pinctrl_get_device_gpio_range
>
> pinctrl_get_device_gpio_range() is unable to find any valid
> pin ranges, since nothing has been added to the pinctrldev_list yet.
> so the range can't be found, and the operation fails with -EPROBE_DEFER.
>
> This patch fixes the issue by adding the "gpio-ranges" property to
> the pinctrl device node of all upstream Qcom SoC. The pin ranges are
> then added by the gpio core.
>
> In order to remain compatible with older, existing DTs (and ACPI)
> a check for the "gpio-ranges" property has been added to
> msm_gpio_init(). This prevents the driver of adding the same entry
> to the pinctrldev_list twice.
>
> Reported-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
> Tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [ipq4019]
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v5 3/4] ARM: dts: qcom: add gpio-ranges property
From: Linus Walleij @ 2018-05-24  8:05 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	David Brown, Stephen Boyd, linux-arm-msm, Bjorn Andersson,
	open list:GPIO SUBSYSTEM, Rob Herring, Sven Eckelmann, Andy Gross,
	Linux ARM
In-Reply-To: <0ae3376606a89bcdf3fe753a5c967f7103699e09.1526935804.git.chunkeey@gmail.com>

On Mon, May 21, 2018 at 10:57 PM, Christian Lamparter
<chunkeey@gmail.com> wrote:

> This patch adds the gpio-ranges property to almost all of
> the Qualcomm ARM platforms that utilize the pinctrl-msm
> framework.
>
> The gpio-ranges property is part of the gpiolib subsystem.
> As a result, the binding text is available in section
> "2.1 gpio- and pin-controller interaction" of
> Documentation/devicetree/bindings/gpio/gpio.txt
>
> For more information please see the patch titled:
> "pinctrl: msm: fix gpio-hog related boot issues" from
> this series.
>
> Reported-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
> Tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [ipq4019]
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I guess Andy will apply this?

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v5 4/4] gpiolib: discourage gpiochip_add_pin[group]_range for DT pinctrls
From: Linus Walleij @ 2018-05-24  8:07 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	David Brown, Stephen Boyd, linux-arm-msm, Bjorn Andersson,
	open list:GPIO SUBSYSTEM, Rob Herring, Sven Eckelmann, Andy Gross,
	Linux ARM
In-Reply-To: <2969992a1005d7e7f4ea23d4c684d2f10d4a0aca.1526935804.git.chunkeey@gmail.com>

On Mon, May 21, 2018 at 10:57 PM, Christian Lamparter
<chunkeey@gmail.com> wrote:

> This patch adds the stern warning to the kerneldoc text of both
> gpiochip_add_pin[group]_range() functions in hope of detering
> developers from ever using them in their DeviceTree-supported
> pinctrl drivers in the future.
>
> For anyone affected: Please refer to Section 2.1 of
> Documentation/devicetree/bindings/gpio/gpio.txt on how to
> bind pinctrl and gpio drivers via the "gpio-ranges" property.
>
> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>

I'm a big fan of this patch, so applied.

I wouldn't mind a pr_info() warning about it at runtime too,
but this is nice.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH/RFC v4 2/4] usb: gadget: udc: renesas_usb3: Add register of usb role switch
From: Geert Uytterhoeven @ 2018-05-24  8:17 UTC (permalink / raw)
  To: Rob Herring
  Cc: Yoshihiro Shimoda, gregkh@linuxfoundation.org,
	mark.rutland@arm.com, heikki.krogerus@linux.intel.com,
	hdegoede@redhat.com, andy.shevchenko@gmail.com,
	linux-usb@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	devicetree@vger.kernel.org
In-Reply-To: <CAL_JsqJv-gZ4Ya6KCOtvQhzBPdLcqkU7c+kdH_TdPW9qvhtmxQ@mail.gmail.com>

Hi Rob,

On Wed, May 23, 2018 at 5:00 PM, Rob Herring <robh@kernel.org> wrote:
> On Wed, May 23, 2018 at 1:52 AM, Yoshihiro Shimoda
> <yoshihiro.shimoda.uh@renesas.com> wrote:
>>> From: Rob Herring, Sent: Wednesday, May 23, 2018 2:13 AM
>>> On Tue, May 22, 2018 at 09:01:07PM +0900, Yoshihiro Shimoda wrote:
>>> > --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt
>>> > +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt
>>> > @@ -19,6 +19,9 @@ Required properties:
>>> >  Optional properties:
>>> >    - phys: phandle + phy specifier pair
>>> >    - phy-names: must be "usb"
>>> > +  - The connection to a usb3.0 host node needs by using OF graph bindings for
>>> > +    usb role switch.
>>> > +   - port@0 = USB3.0 host port.
>>>
>>> On the host side, this might conflict with the USB connector binding.
>>>
>>> I would either make sure this can work with the connector binding by
>>> having 2 endpoints on the HS or SS port or just use the 'companion'
>>> property defined in usb-generic.txt.
>>
>> I don't understand the first one now... This means the renesas_usb3 should follow
>> USB connector binding and have 2 endpoints for the usb role switch to avoid
>> the conflict like below?
>>  - port1@0: Super Speed (SS), present in SS capable connectors (from usb-connector.txt).
>>  - port1@1: USB3.0 host port.
>
> I'm confused, SS and USB3.0 are the same essentially. It would be:
>
> port@1/endpoint@0: SS host port
> port@1/endpoint@1: SS device port
>
>> About the 'companion' in usb-generic.txt, the property intends to be used for EHCI or host side
>> like the commit log [1]. If there is accept to use 'companion' for this patch, I think it will
>> be simple to achieve this role switch feature. However, in last month, I submitted a similar patch [2]
>> that has "renesas,host" property, but I got reply from Andy [3] and Heikki [4]. So, I'm
>> trying to improve the device connection framework [5] now.
>
> I think this case is rare enough that we don't need a general solution
> using OF graph, so I'm fine with a simple, single property to link the
> 2 nodes. Either reusing "companion" or "renesas,host" is fine by me.

I'd go for the standard "companion" over "renesas,host"[*].

[*] Doh, we have another one ("renesas,bonding"), invented when I wasn't
    aware of the existence of "companion" yet...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v5 1/3] phy: Power on PHY before start Serdes configuration
From: Vivek Gautam @ 2018-05-24  8:17 UTC (permalink / raw)
  To: Can Guo, subhashj, asutoshd, mgautam, kishon, robh+dt,
	mark.rutland
  Cc: linux-kernel, devicetree
In-Reply-To: <20180523034712.3420-2-cang@codeaurora.org>

Hi Can,


On 5/23/2018 9:17 AM, Can Guo wrote:
> PHYs should be powered on before register configuration starts.
>
> Signed-off-by: Can Guo <cang@codeaurora.org>
> ---

Thanks for fixing this.

>   drivers/phy/qualcomm/phy-qcom-qmp.c | 6 ++++++
>   1 file changed, 6 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 97ef942..9bfdba1 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -1000,6 +1000,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
>   			     SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
>   	}
>   
> +	/*
> +	 * Pull out PHY from POWER DOWN state.
> +	 * This is active low enable signal to power-down PHY.
> +	 */
> +	qphy_setbits(pcs, QPHY_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
> +

Thanks. This is in sync with the requirements of USB and UFS phys across 
platforms
using this qmp phy driver, viz. 8996 and 845.
However, as discussed with you offline the PCIe phy has different 
requirement.
PCIe phy on 8996 doesn't need the QPHY_POWER_DOWN_CONTROL (pcs level 
power down)
before configuring the phys. Rather COM_POWER_DOWN_CONTROL is enough.
It needs the QPHY_POWER_DOWN_CONTROL after programming the
serdes, tx, rx, and pcs blocks, and right before doing SW_RESET, and 
START_CONTROL.

So we should just do the above QPHY_POWER_DOWN_CONTROL in
qcom_qmp_phy_com_init() only for non-PCIe phys at the moment, and
skip the QPHY_POWER_DOWN_CONTROL in qcom_qmp_phy_init()
for these non-PCIe phys.

Thanks
Vivek

>   	/* Serdes configuration */
>   	qcom_qmp_phy_configure(serdes, cfg->regs, cfg->serdes_tbl,
>   			       cfg->serdes_tbl_num);

^ permalink raw reply

* RE: [RESEND PATCH 3/4] dt-bindings: PCI: cadence: Add DT bindings for optional PHYs
From: Alan Douglas @ 2018-05-24  8:22 UTC (permalink / raw)
  To: Rob Herring
  Cc: bhelgaas@google.com, kishon@ti.com, lorenzo.pieralisi@arm.com,
	linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.com, cyrille.pitchen@free-electrons.com
In-Reply-To: <20180523185229.GA7457@rob-hp-laptop>

On  23 May 2018 19:52, Rob Herring wrote:
> On Tue, May 22, 2018 at 02:32:32PM +0100, Alan Douglas wrote:
> > Update DT documentation to include optional PHYs for cadence PCIe
> > host and endpoint controllers.
> >
> > Signed-off-by: Alan Douglas <adouglas@cadence.com>
> > ---
> >  Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt   | 4 ++++
> >  Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt | 2 ++
> >  2 files changed, 6 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-
> ep.txt
> > index 9a305237..e40c635 100644
> > --- a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
> > +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
> > @@ -9,6 +9,8 @@ Required properties:
> >
> >  Optional properties:
> >  - max-functions: Maximum number of functions that can be configured (default 1).
> > +- phys: From PHY bindings: List of Generic PHY phandles.
> > +- phy-names:  List of names to identify the PHY.
> 
> You need to define how many. I'd assume one, but I guess your example is
> 1 per lane.
> 
I can update the description in v3 as follows:
 - phys: From PHY bindings: List of Generic PHY phandles. One per lane if more than one in the
  list.  If only one PHY listed it must manage all lanes. 
 - phy-names:  List of names to identify the PHY, one for each in the list.
> >
> >  Example:
> >
> > @@ -19,4 +21,6 @@ pcie@fc000000 {
> >  	reg-names = "reg", "mem";
> >  	cdns,max-outbound-regions = <16>;
> >  	max-functions = /bits/ 8 <8>;
> > +	phys = <&ep_phy0 &ep_phy1>;
> > +	phy-names = "pcie-lane0","pcie-lane1";
> >  };





^ permalink raw reply

* Re: Re: [PATCH 12/15] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
From: Maxime Ripard @ 2018-05-24  8:27 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, wens-jdAy2FN1RRM,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4018914.loHx9iTxYh@jernej-laptop>

[-- Attachment #1: Type: text/plain, Size: 5778 bytes --]

On Mon, May 21, 2018 at 05:02:23PM +0200, Jernej Škrabec wrote:
> Hi,
> 
> Dne ponedeljek, 21. maj 2018 ob 10:12:53 CEST je Maxime Ripard napisal(a):
> > On Sat, May 19, 2018 at 08:31:24PM +0200, Jernej Skrabec wrote:
> > > Expand HDMI PHY clock driver to support second clock parent.
> > > 
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h      |  6 +-
> > >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c     | 29 ++++++-
> > >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 90 ++++++++++++++++------
> > >  3 files changed, 98 insertions(+), 27 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > > b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 801a17222762..aadbe0a10b0c
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > > @@ -98,7 +98,8 @@
> > > 
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN		BIT(29)
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
> > > 
> > > -#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL	BIT(26)
> > > +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
> > > +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT	26
> > > 
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
> > >  #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
> > > 
> > > @@ -190,6 +191,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi
> > > *hdmi);
> > > 
> > >  void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
> > >  const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
> > > 
> > > -int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
> > > +int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
> > > +			 bool second_parent);
> > > 
> > >  #endif /* _SUN8I_DW_HDMI_H_ */
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > > b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index deba47ed69d8..7a911f0a3ae3
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > > @@ -183,7 +183,13 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi
> > > *hdmi,> 
> > >  	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
> > >  	
> > >  			   SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
> > > 
> > > -	regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
> > > +	/*
> > > +	 * NOTE: We have to be careful not to overwrite PHY parent
> > > +	 * clock selection bit and clock divider.
> > > +	 */
> > > +	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
> > > +			   ~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
> > > +			   pll_cfg1_init);
> > 
> > It feels like it belongs in a separate patch.
> 
> Why? clk_set_rate() on HDMI PHY clock is called before this function, so 
> SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL bit is already set to correct value. Original 
> code doesn't take this into account and sets it to 0 here in all cases, which 
> obviously is not right.
> 
> If you insist on splitting this in new patch, it has to be applied before 
> clock changes. It would also need to include "reset PLL clock configuration" 
> chunk (next change in this patch), otherwise other SoCs with only one parent 
> could get 1 there, which is obviously wrong. Note that I didn't really tested 
> if default value of this bit is 0 or 1, but I wouldn't really like to depend 
> on default values.

I don't have a strong feeling about this, but to me, the fact that you
don't want to overwrite the muxing bit because the clock might use it
is sensible in itself, disregarding the fact that the clock *will* use
it.

> 
> > 
> > >  	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
> > >  	
> > >  			   (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
> > >  			   pll_cfg2_init);
> > > 
> > > @@ -352,6 +358,10 @@ static void sun8i_hdmi_phy_init_h3(struct
> > > sun8i_hdmi_phy *phy)> 
> > >  			   SUN8I_HDMI_PHY_ANA_CFG3_SCLEN |
> > >  			   SUN8I_HDMI_PHY_ANA_CFG3_SDAEN);
> > > 
> > > +	/* reset PLL clock configuration */
> > > +	regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, 0);
> > > +	regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG, 0);
> > > +
> > 
> > Ditto,
> > 
> > > +
> > > +		/*
> > > +		 * Even though HDMI PHY clock doesn't have enable/disable
> > > +		 * handlers, we have to enable it. Otherwise it could happen
> > > +		 * that parent PLL is not enabled by clock framework in a
> > > +		 * highly unlikely event when parent PLL is used solely for
> > > +		 * HDMI PHY clock.
> > > +		 */
> > > +		clk_prepare_enable(phy->clk_phy);
> > 
> > The implementation of the clock doesn't really matter in our API
> > usage. If we're using a clock, we have to call
> > clk_prepare_enable. That's documented everywhere, and mentionning how
> > the clock is implemented is an abstraction leakage and it's
> > irrelevant. I'd simply remove the comment here.
> > 
> > And it should be in a separate patch as well.
> 
> OK. Should I add Fixes tag, since current code obviously is not by the specs? 
> It could still get in 4.17...

Yep!

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/5] gpio: syscon: Add gpio-syscon for rockchip
From: Linus Walleij @ 2018-05-24  8:28 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Rob Herring, Levin Du, open list:ARM/Rockchip SoC..., Wayne Chou,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM,
	Mark Rutland,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <1685755.J6GI985WX3@diego>

On Wed, May 23, 2018 at 5:12 PM, Heiko Stübner <heiko@sntech.de> wrote:

> So the gpio controller should definitly also be a subnode.
>
> The gpio in question is called "mute", so I'd think the gpio-syscon driver
> should just define a "rockchip,rk3328-gpio-mute" compatible and contain
> all the register voodoo in the driver itself and not define it in the dt.
>
> So it should probably look like
>
> grf: syscon at ff100000 {
>         compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
>
>         [all the other syscon sub-devices]
>
>         gpio_mute: gpio-mute {
>                 compatible = "rockchip,rk3328-gpio-mute";
>                 gpio-controller;
>                 #gpio-cells = <2>;
>         };

I'm sceptic.

That doesn't sound like "general purpose input output" at all.

It sounds like special purpose, for a mute button.

Does it use IRQ? I would recommend implementing
drivers/input/keyboard/syscon-keys.c in the same vein
as drivers/leds/leds-syscon.c so you can avoid indirection
through GPIO for no good reason at all.

I already have other good uses for such a generic
input driver.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 2/5] gpio: syscon: Add gpio-syscon for rockchip
From: Heiko Stübner @ 2018-05-24  8:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Levin Du, open list:ARM/Rockchip SoC..., Wayne Chou,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM,
	Mark Rutland,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CACRpkdYCdNZ=ASw1uz4zKXC4AMd1EGbvG_G5K5cwSpH5eGPgKA@mail.gmail.com>

Hi Linus,

Am Donnerstag, 24. Mai 2018, 10:28:44 CEST schrieb Linus Walleij:
> On Wed, May 23, 2018 at 5:12 PM, Heiko Stübner <heiko@sntech.de> wrote:
> > So the gpio controller should definitly also be a subnode.
> > 
> > The gpio in question is called "mute", so I'd think the gpio-syscon driver
> > should just define a "rockchip,rk3328-gpio-mute" compatible and contain
> > all the register voodoo in the driver itself and not define it in the dt.
> > 
> > So it should probably look like
> > 
> > grf: syscon at ff100000 {
> > 
> >         compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
> >         
> >         [all the other syscon sub-devices]
> >         
> >         gpio_mute: gpio-mute {
> >         
> >                 compatible = "rockchip,rk3328-gpio-mute";
> >                 gpio-controller;
> >                 #gpio-cells = <2>;
> >         
> >         };
> 
> I'm sceptic.
> 
> That doesn't sound like "general purpose input output" at all.
> 
> It sounds like special purpose, for a mute button.
> 
> Does it use IRQ? I would recommend implementing
> drivers/input/keyboard/syscon-keys.c in the same vein
> as drivers/leds/leds-syscon.c so you can avoid indirection
> through GPIO for no good reason at all.

To quote Levin from the other mail:
--------
The "mute" pin is a output only GPIO, which is already supported by 
setting flags in the gpio-syscon
  driver. And yes, this pin has a defined function, but can also be used 
for general purpose operation.
--------

So to summarize, the documentation calls it "mute", but it is usable as
a general pin, which is the reason Levin is working on it - because on his
board this pin is used to switch between two voltages (aka a gpio-regulator)
for the sdmmc controller [3.3V + 1.8V].

Available pin settings are output-enable + of course the high/low setting
and I think I remember there is even a pull setting for it in the GRF 
somewhere - but my memory might be fuzzy here.


Heiko

^ permalink raw reply

* Re: [PATCH 05/15] drm/sun4i: Add TCON TOP driver
From: Maxime Ripard @ 2018-05-24  8:43 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: wens-jdAy2FN1RRM, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <5965231.6ucpJrPIQ5@jernej-laptop>

[-- Attachment #1: Type: text/plain, Size: 2356 bytes --]

Hi,

On Mon, May 21, 2018 at 05:15:15PM +0200, Jernej Škrabec wrote:
> > > +	/*
> > > +	 * Default register values might have some reserved bits set, which
> > > +	 * prevents TCON TOP from working properly. Set them to 0 here.
> > > +	 */
> > > +	writel(0, tcon_top->regs + TCON_TOP_PORT_SEL_REG);
> > > +	writel(0, tcon_top->regs + TCON_TOP_GATE_SRC_REG);
> > > +
> > > +	for (i = 0; i < CLK_NUM; i++) {
> > > +		const char *parent_name = "bus-tcon-top";
> > 
> > I guess retrieving the parent's clock name at runtime would be more
> > flexible.
> 
> It is, but will it ever be anything else?

Probably not, but when the complexity is exactly the same (using
__clk_get_name), we'd better use the more appropriate solution. If we
ever need to change that clock name, or to use the driver with an SoC
that wouldn't have the same clock name for whatever reason, it will
just work.

> > > +		struct clk_init_data init;
> > > +		struct clk_gate *gate;
> > > +
> > > +		gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
> > > +		if (!gate) {
> > > +			ret = -ENOMEM;
> > > +			goto err_disable_clock;
> > > +		}
> > > +
> > > +		init.name = gates[i].name;
> > > +		init.ops = &clk_gate_ops;
> > > +		init.flags = CLK_IS_BASIC;
> > > +		init.parent_names = &parent_name;
> > > +		init.num_parents = 1;
> > > +
> > > +		gate->reg = tcon_top->regs + TCON_TOP_GATE_SRC_REG;
> > > +		gate->bit_idx = gates[i].bit;
> > > +		gate->lock = &tcon_top->reg_lock;
> > > +		gate->hw.init = &init;
> > > +
> > > +		ret = devm_clk_hw_register(dev, &gate->hw);
> > > +		if (ret)
> > > +			goto err_disable_clock;
> > 
> > Isn't it what clk_hw_register_gate is doing?
> 
> Almost, but not exactly. My goal was to use devm_* functions, so there is no 
> need to do any special cleanup.

Is it the only difference? If so, you can just create a
devm_clk_hw_register gate.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [RESEND PATCH 2/5] mtd: rawnand: add NVIDIA Tegra NAND Flash controller driver
From: Stefan Agner @ 2018-05-24  8:46 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: dwmw2, computersforpeace, marek.vasut, robh+dt, mark.rutland,
	thierry.reding, mturquette, sboyd, dev, miquel.raynal, richard,
	marcel, krzk, digetx, benjamin.lindqvist, jonathanh, pdeschrijver,
	pgaikwad, mirza.krak, linux-mtd, linux-tegra, devicetree,
	linux-kernel, linux-clk
In-Reply-To: <20180523161810.0ed9fe80@bbrezillon>

Hi Boris,

Thanks for the initial review! One small question below:

On 23.05.2018 16:18, Boris Brezillon wrote:
> Hi Stefan,
> 
> On Tue, 22 May 2018 14:07:06 +0200
> Stefan Agner <stefan@agner.ch> wrote:
>> +
>> +struct tegra_nand {
>> +	void __iomem *regs;
>> +	struct clk *clk;
>> +	struct gpio_desc *wp_gpio;
>> +
>> +	struct nand_chip chip;
>> +	struct device *dev;
>> +
>> +	struct completion command_complete;
>> +	struct completion dma_complete;
>> +	bool last_read_error;
>> +
>> +	dma_addr_t data_dma;
>> +	void *data_buf;
>> +	dma_addr_t oob_dma;
>> +	void *oob_buf;
>> +
>> +	int cur_chip;
>> +};
> 
> This struct should be split in 2 structures: one representing the NAND
> controller and one representing the NAND chip:
> 
> struct tegra_nand_controller {
> 	struct nand_hw_control base;
> 	void __iomem *regs;
> 	struct clk *clk;
> 	struct device *dev;
> 	struct completion command_complete;
> 	struct completion dma_complete;
> 	bool last_read_error;
> 	int cur_chip;
> };
> 
> struct tegra_nand {
> 	struct nand_chip base;
> 	dma_addr_t data_dma;
> 	void *data_buf;
> 	dma_addr_t oob_dma;
> 	void *oob_buf;
> };

Is there a particular reason why you would leave DMA buffers in the chip
structure? It seems that is more a controller thing...

If I move them, then struct tegra_nand would be basically empty. Can I
just use struct nand_chip and have no driver specific chip abstraction?

--
Stefan

> 
>> +
>> +static inline struct tegra_nand *to_tegra_nand(struct mtd_info *mtd)
>> +{
>> +	struct nand_chip *chip = mtd_to_nand(mtd);
>> +
>> +	return nand_get_controller_data(chip);
> 
> then you can just do:
> 
> 	return container_of(chip, struct tegra_nand, base);
> 
>> +}
>> +
>> +static int tegra_nand_ooblayout_16_ecc(struct mtd_info *mtd, int section,
>> +				       struct mtd_oob_region *oobregion)
>> +{
>> +	if (section > 0)
>> +		return -ERANGE;
>> +
>> +	oobregion->offset = 4;
>> +	oobregion->length = 4;
>> +
>> +	return 0;
>> +}
>> +
>> +static int tegra_nand_ooblayout_16_free(struct mtd_info *mtd, int section,
>> +					struct mtd_oob_region *oobregion)
>> +{
>> +	if (section > 0)
>> +		return -ERANGE;
>> +
>> +	oobregion->offset = 8;
>> +	oobregion->length = 8;
>> +
>> +	return 0;
>> +}
> 
> ...
> 
>> +
>> +static int tegra_nand_ooblayout_224_ecc(struct mtd_info *mtd, int section,
>> +				       struct mtd_oob_region *oobregion)
>> +{
>> +	if (section > 0)
>> +		return -ERANGE;
>> +
>> +	oobregion->offset = 4;
>> +	oobregion->length = 144;
>> +
>> +	return 0;
>> +}
>> +
>> +static int tegra_nand_ooblayout_224_free(struct mtd_info *mtd, int section,
>> +					struct mtd_oob_region *oobregion)
>> +{
>> +	if (section > 0)
>> +		return -ERANGE;
>> +
>> +	oobregion->offset = 148;
>> +	oobregion->length = 76;
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct mtd_ooblayout_ops tegra_nand_oob_224_ops = {
>> +	.ecc = tegra_nand_ooblayout_224_ecc,
>> +	.free = tegra_nand_ooblayout_224_free,
>> +};
>> +
> 
> I'm pretty sure we can find a pattern here to avoid defining a new
> mtd_ooblayout_ops for each OOB size.
> 
>> +static irqreturn_t tegra_nand_irq(int irq, void *data)
>> +{
>> +	struct tegra_nand *nand = data;
>> +	u32 isr, dma;
>> +
>> +	isr = readl(nand->regs + ISR);
>> +	dma = readl(nand->regs + DMA_CTRL);
>> +	dev_dbg(nand->dev, "isr %08x\n", isr);
>> +
>> +	if (!isr && !(dma & DMA_CTRL_IS_DONE))
>> +		return IRQ_NONE;
>> +
>> +	if (isr & ISR_CORRFAIL_ERR)
>> +		nand->last_read_error = true;
>> +
>> +	if (isr & ISR_CMD_DONE)
>> +		complete(&nand->command_complete);
>> +
>> +	if (isr & ISR_UND)
>> +		dev_dbg(nand->dev, "FIFO underrun\n");
>> +
>> +	if (isr & ISR_OVR)
>> +		dev_dbg(nand->dev, "FIFO overrun\n");
>> +
>> +	/* handle DMA interrupts */
>> +	if (dma & DMA_CTRL_IS_DONE) {
>> +		writel(dma, nand->regs + DMA_CTRL);
>> +		complete(&nand->dma_complete);
>> +	}
>> +
>> +	/* clear interrupts */
>> +	writel(isr, nand->regs + ISR);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static int tegra_nand_cmd(struct nand_chip *chip,
>> +			 const struct nand_subop *subop)
>> +{
>> +	const struct nand_op_instr *instr;
>> +	const struct nand_op_instr *instr_data_in = NULL;
>> +	struct mtd_info *mtd = nand_to_mtd(chip);
>> +	struct tegra_nand *nand = to_tegra_nand(mtd);
>> +	unsigned int op_id = -1, trfr_in_sz = 0, trfr_out_sz = 0, offset = 0;
>> +	bool first_cmd = true;
>> +	bool force8bit;
>> +	u32 cmd = 0;
>> +	u32 value;
>> +
>> +	for (op_id = 0; op_id < subop->ninstrs; op_id++) {
>> +		unsigned int naddrs, i;
>> +		const u8 *addrs;
>> +		u32 addr1 = 0, addr2 = 0;
>> +
>> +		instr = &subop->instrs[op_id];
>> +
>> +		switch (instr->type) {
>> +		case NAND_OP_CMD_INSTR:
>> +			if (first_cmd) {
>> +				cmd |= CMD_CLE;
>> +				writel(instr->ctx.cmd.opcode, nand->regs + CMD_1);
>> +			} else {
>> +				cmd |= CMD_SEC_CMD;
>> +				writel(instr->ctx.cmd.opcode, nand->regs + CMD_2);
>> +			}
>> +			first_cmd = false;
>> +			break;
>> +		case NAND_OP_ADDR_INSTR:
>> +			offset = nand_subop_get_addr_start_off(subop, op_id);
>> +			naddrs = nand_subop_get_num_addr_cyc(subop, op_id);
>> +			addrs = &instr->ctx.addr.addrs[offset];
>> +
>> +			cmd |= CMD_ALE | CMD_ALE_SIZE(naddrs);
>> +			for (i = 0; i < min_t(unsigned int, 4, naddrs); i++)
>> +				addr1 |= *addrs++ << (8 * i);
>> +			naddrs -= i;
>> +			for (i = 0; i < min_t(unsigned int, 4, naddrs); i++)
>> +				addr2 |= *addrs++ << (8 * i);
>> +			writel(addr1, nand->regs + ADDR_1);
>> +			writel(addr2, nand->regs + ADDR_2);
>> +			break;
>> +
>> +		case NAND_OP_DATA_IN_INSTR:
>> +			trfr_in_sz = nand_subop_get_data_len(subop, op_id);
>> +			offset = nand_subop_get_data_start_off(subop, op_id);
>> +
>> +			cmd |= CMD_TRANS_SIZE(trfr_in_sz) | CMD_PIO | CMD_RX | CMD_A_VALID;
>> +
>> +			instr_data_in = instr;
>> +			break;
>> +
>> +		case NAND_OP_DATA_OUT_INSTR:
>> +			trfr_out_sz = nand_subop_get_data_len(subop, op_id);
>> +			offset = nand_subop_get_data_start_off(subop, op_id);
>> +			trfr_out_sz = min_t(size_t, trfr_out_sz, 4);
>> +
>> +			cmd |= CMD_TRANS_SIZE(trfr_out_sz) | CMD_PIO | CMD_TX | CMD_A_VALID;
>> +
>> +			memcpy(&value, instr->ctx.data.buf.out + offset, trfr_out_sz);
>> +			writel(value, nand->regs + RESP);
>> +
>> +			break;
>> +		case NAND_OP_WAITRDY_INSTR:
>> +			cmd |= CMD_RBSY_CHK;
>> +			break;
>> +
>> +		}
>> +	}
>> +
>> +
>> +	cmd |= CMD_GO | CMD_CE(nand->cur_chip);
>> +	writel(cmd, nand->regs + CMD);
>> +	wait_for_completion(&nand->command_complete);
>> +
>> +	if (instr_data_in) {
>> +		u32 value;
>> +		size_t n = min_t(size_t, trfr_in_sz, 4);
>> +
>> +		value = readl(nand->regs + RESP);
>> +		memcpy(instr_data_in->ctx.data.buf.in + offset, &value, n);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct nand_op_parser tegra_nand_op_parser = NAND_OP_PARSER(
>> +	NAND_OP_PARSER_PATTERN(tegra_nand_cmd,
>> +		NAND_OP_PARSER_PAT_CMD_ELEM(true),
>> +		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
>> +		NAND_OP_PARSER_PAT_CMD_ELEM(true),
>> +		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
>> +	NAND_OP_PARSER_PATTERN(tegra_nand_cmd,
>> +		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 4)),
>> +	NAND_OP_PARSER_PATTERN(tegra_nand_cmd,
>> +		NAND_OP_PARSER_PAT_CMD_ELEM(true),
>> +		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 8),
>> +		NAND_OP_PARSER_PAT_CMD_ELEM(true),
>> +		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
>> +		NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 4)),
>> +	);
>> +
>> +static int tegra_nand_exec_op(struct nand_chip *chip,
>> +			     const struct nand_operation *op,
>> +			     bool check_only)
>> +{
>> +	return nand_op_parser_exec_op(chip, &tegra_nand_op_parser, op,
>> +				      check_only);
>> +}
> 
> Missing empty line here.
> 
>> +static void tegra_nand_select_chip(struct mtd_info *mtd, int chip)
>> +{
>> +	struct tegra_nand *nand = to_tegra_nand(mtd);
>> +
>> +	nand->cur_chip = chip;
>> +}
> 
> ...
> 
>> +
>> +static void tegra_nand_setup_chiptiming(struct tegra_nand *nand)
>> +{
>> +	struct nand_chip *chip = &nand->chip;
>> +	int mode;
>> +
>> +	mode = onfi_get_async_timing_mode(chip);
>> +	if (mode == ONFI_TIMING_MODE_UNKNOWN)
>> +		mode = chip->onfi_timing_mode_default;
>> +	else
>> +		mode = fls(mode);
>> +
>> +	tegra_nand_setup_timing(nand, mode);
> 
> Hm, you shouldn't do that. Let the core select the timing mode for you,
> and just implement the ->setup_data_interface() hook.
> 
>> +}
>> +
>> +static int tegra_nand_probe(struct platform_device *pdev)
>> +{
>> +	struct reset_control *rst;
>> +	struct tegra_nand *nand;
>> +	struct nand_chip *chip;
>> +	struct mtd_info *mtd;
>> +	struct resource *res;
>> +	unsigned long value;
>> +	int irq, err = 0;
>> +
>> +	nand = devm_kzalloc(&pdev->dev, sizeof(*nand), GFP_KERNEL);
>> +	if (!nand)
>> +		return -ENOMEM;
>> +
>> +	nand->dev = &pdev->dev;
>> +
>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	nand->regs = devm_ioremap_resource(&pdev->dev, res);
>> +	if (IS_ERR(nand->regs))
>> +		return PTR_ERR(nand->regs);
>> +
>> +	irq = platform_get_irq(pdev, 0);
>> +	err = devm_request_irq(&pdev->dev, irq, tegra_nand_irq, 0,
>> +			       dev_name(&pdev->dev), nand);
>> +	if (err)
>> +		return err;
>> +
>> +	rst = devm_reset_control_get(&pdev->dev, "nand");
>> +	if (IS_ERR(rst))
>> +		return PTR_ERR(rst);
>> +
>> +	nand->clk = devm_clk_get(&pdev->dev, "nand");
>> +	if (IS_ERR(nand->clk))
>> +		return PTR_ERR(nand->clk);
>> +
>> +	nand->wp_gpio = gpiod_get_optional(&pdev->dev, "wp-gpios",
>> +					   GPIOD_OUT_HIGH);
>> +	if (IS_ERR(nand->wp_gpio))
>> +		return PTR_ERR(nand->wp_gpio);
>> +
>> +	err = clk_prepare_enable(nand->clk);
>> +	if (err)
>> +		return err;
>> +
>> +	reset_control_assert(rst);
>> +	udelay(2);
>> +	reset_control_deassert(rst);
>> +
>> +	value = HWSTATUS_RDSTATUS_MASK(1) | HWSTATUS_RDSTATUS_VALUE(0) |
>> +		HWSTATUS_RBSY_MASK(NAND_STATUS_READY) |
>> +		HWSTATUS_RBSY_VALUE(NAND_STATUS_READY);
>> +	writel(NAND_CMD_STATUS, nand->regs + HWSTATUS_CMD);
>> +	writel(value, nand->regs + HWSTATUS_MASK);
>> +
>> +	init_completion(&nand->command_complete);
>> +	init_completion(&nand->dma_complete);
>> +
>> +	/* clear interrupts */
>> +	value = readl(nand->regs + ISR);
>> +	writel(value, nand->regs + ISR);
>> +
>> +	writel(DMA_CTRL_IS_DONE, nand->regs + DMA_CTRL);
>> +
>> +	/* enable interrupts */
>> +	value = IER_UND | IER_OVR | IER_CMD_DONE | IER_ECC_ERR | IER_GIE;
>> +	writel(value, nand->regs + IER);
>> +
>> +	/* reset config */
>> +	writel(0, nand->regs + CFG);
>> +
>> +	chip = &nand->chip;
>> +	mtd = nand_to_mtd(chip);
>> +
>> +	mtd->dev.parent = &pdev->dev;
>> +	mtd->name = "tegra_nand";
>> +	mtd->owner = THIS_MODULE;
>> +
>> +	nand_set_flash_node(chip, pdev->dev.of_node);
>> +	nand_set_controller_data(chip, nand);
>> +
>> +	chip->options = NAND_NO_SUBPAGE_WRITE;
>> +	chip->exec_op = tegra_nand_exec_op;
>> +	chip->select_chip = tegra_nand_select_chip;
>> +	tegra_nand_setup_timing(nand, 0);
>> +
>> +	err = nand_scan_ident(mtd, 1, NULL);
>> +	if (err)
>> +		goto err_disable_clk;
>> +
>> +	if (chip->bbt_options & NAND_BBT_USE_FLASH)
>> +		chip->bbt_options |= NAND_BBT_NO_OOB;
>> +
>> +	nand->data_buf = dmam_alloc_coherent(&pdev->dev, mtd->writesize,
>> +					    &nand->data_dma, GFP_KERNEL);
>> +	if (!nand->data_buf) {
>> +		err = -ENOMEM;
>> +		goto err_disable_clk;
>> +	}
>> +
>> +	nand->oob_buf = dmam_alloc_coherent(&pdev->dev, mtd->oobsize,
>> +					    &nand->oob_dma, GFP_KERNEL);
>> +	if (!nand->oob_buf) {
>> +		err = -ENOMEM;
>> +		goto err_disable_clk;
>> +	}
>> +
>> +	chip->ecc.mode = NAND_ECC_HW;
>> +	chip->ecc.size = 512;
>> +	chip->ecc.read_page = tegra_nand_read_page;
>> +	chip->ecc.write_page = tegra_nand_write_page;
> 
> I'd like to have raw accessors implemented here.
> 
> That was just a quick review focusing mainly on architectural issues so
> that you can start working on a v2.
> 
> Regards,
> 
> Boris

^ permalink raw reply

* Re: [PATCH v2 2/5] gpio: syscon: Add gpio-syscon for rockchip
From: Linus Walleij @ 2018-05-24  8:47 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Mark Rutland, Rob Herring, Wayne Chou,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org,
	open list:ARM/Rockchip SoC..., Levin Du,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <2044895.BqI5yRtle6@diego>

On Thu, May 24, 2018 at 10:35 AM, Heiko Stübner <heiko@sntech.de> wrote:
> Am Donnerstag, 24. Mai 2018, 10:28:44 CEST schrieb Linus Walleij:
>> On Wed, May 23, 2018 at 5:12 PM, Heiko Stübner <heiko@sntech.de> wrote:
>> > So the gpio controller should definitly also be a subnode.
>> >
>> > The gpio in question is called "mute", so I'd think the gpio-syscon driver
>> > should just define a "rockchip,rk3328-gpio-mute" compatible and contain
>> > all the register voodoo in the driver itself and not define it in the dt.
>> >
>> > So it should probably look like
>> >
>> > grf: syscon at ff100000 {
>> >
>> >         compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
>> >
>> >         [all the other syscon sub-devices]
>> >
>> >         gpio_mute: gpio-mute {
>> >
>> >                 compatible = "rockchip,rk3328-gpio-mute";
>> >                 gpio-controller;
>> >                 #gpio-cells = <2>;
>> >
>> >         };
>>
>> I'm sceptic.
>>
>> That doesn't sound like "general purpose input output" at all.
>>
>> It sounds like special purpose, for a mute button.
>>
>> Does it use IRQ? I would recommend implementing
>> drivers/input/keyboard/syscon-keys.c in the same vein
>> as drivers/leds/leds-syscon.c so you can avoid indirection
>> through GPIO for no good reason at all.
>
> To quote Levin from the other mail:
> --------
> The "mute" pin is a output only GPIO, which is already supported by
> setting flags in the gpio-syscon
>   driver. And yes, this pin has a defined function, but can also be used
> for general purpose operation.
> --------
>
> So to summarize, the documentation calls it "mute", but it is usable as
> a general pin, which is the reason Levin is working on it - because on his
> board this pin is used to switch between two voltages (aka a gpio-regulator)
> for the sdmmc controller [3.3V + 1.8V].

OK then, I was wrong! :)

Go ahead with this, sorry for the fuzz.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox