Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v2 4/7] Bluetooth: Add new quirk for non-persistent setup settings
From: Sean Wang @ 2018-05-23 14:09 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Mark Rutland, devicetree, Johan Hedberg, LKML, BlueZ development,
	Rob Herring, linux-mediatek, linux-arm-kernel
In-Reply-To: <B82BB5F4-E197-4915-A543-C5FF9A5A41F1@holtmann.org>

On Wed, 2018-05-23 at 14:31 +0200, Marcel Holtmann wrote:
> 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
> 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                                   .....           
< 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                                   .....           
< 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...       
> 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 
< 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
< 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

^ permalink raw reply

* Re: [PATCH v7 3/3] gpio: pca953x: fix address calculation for pcal6524
From: Pavel Machek @ 2018-05-23 14:06 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: galak, andy.shevchenko, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Linus Walleij, Alexandre Courbot, devicetree,
	linux-gpio, linux-kernel, letux-kernel, kernel
In-Reply-To: <e70e83f07aebaf702fef90a9fac61e41d8b558b0.1526533188.git.hns@goldelico.com>

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

On Thu 2018-05-17 06:59:49, H. Nikolaus Schaller wrote:
> The register constants are so far defined in a way that they fit
> for the pcal9555a when shifted by the number of banks, i.e. are
> multiplied by 2 in the accessor function.
> 
> Now, the pcal6524 has 3 banks which means the relative offset
> is multiplied by 4 for the standard registers.
> 
> Simply applying the bit shift to the extended registers gives
> a wrong result, since the base offset is already included in
> the offset.
> 
> Therefore, we have to add code to the 24 bit accessor functions
> that adjusts the register number for these exended registers.
> 
> The formula finally used was developed and proposed by
> Andy Shevchenko <andy.shevchenko@gmail.com>.
> 
> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
>  drivers/gpio/gpio-pca953x.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
> index c682921d7019..4ad553f4e41f 100644
> --- a/drivers/gpio/gpio-pca953x.c
> +++ b/drivers/gpio/gpio-pca953x.c
> @@ -222,9 +222,11 @@ static int pca957x_write_regs_16(struct pca953x_chip *chip, int reg, u8 *val)
>  static int pca953x_write_regs_24(struct pca953x_chip *chip, int reg, u8 *val)
>  {
>  	int bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ);
> +	int addr = (reg & PCAL_GPIO_MASK) << bank_shift;
> +	int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1;

Is this reasonable to do on each register access? Compiler will not be
able to optimize out fls and shifts, right?

								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply

* Re: [PATCH v2 09/16] irqchip/irq-mvebu-sei: add new driver for Marvell SEI
From: Marc Zyngier @ 2018-05-23 14:05 UTC (permalink / raw)
  To: Miquel Raynal, Thomas Gleixner, Jason Cooper, Catalin Marinas,
	Will Deacon, Andrew Lunn, Gregory Clement, Sebastian Hesselbarth
  Cc: Rob Herring, Mark Rutland, devicetree, linux-arm-kernel,
	Thomas Petazzoni, Antoine Tenart, Maxime Chevallier, Nadav Haklai,
	Haim Boot, Hanna Hawa, linux-kernel
In-Reply-To: <20180522094042.24770-10-miquel.raynal@bootlin.com>

On 22/05/18 10:40, Miquel Raynal wrote:
> This is a cascaded interrupt controller in the AP806 GIC that collapses
> SEIs (System Error Interrupt) coming from the AP and the CPs (through
> the ICU).
> 
> The SEI handles up to 64 interrupts. The first 21 interrupts are wired
> and come from the AP. The next 43 interrupts are from the CPs and are

wired to the AP (no interrupts come from it)

> triggered through MSI messages. To handle this complexity, the driver
> has to declare to the upper layer: one IRQ domain for the wired
> interrupts, one IRQ domain for the MSIs; and acts as a MSI server

s/server/controller/

> ('parent') by declaring an MSI domain.
> 
> Suggested-by: Haim Boot <hayim@marvell.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  drivers/irqchip/Kconfig         |   3 +
>  drivers/irqchip/Makefile        |   1 +
>  drivers/irqchip/irq-mvebu-sei.c | 422 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 426 insertions(+)
>  create mode 100644 drivers/irqchip/irq-mvebu-sei.c
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index e9233db16e03..922e2a919cf3 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -310,6 +310,9 @@ config MVEBU_ODMI
>  config MVEBU_PIC
>  	bool
>  
> +config MVEBU_SEI
> +        bool
> +
>  config LS_SCFG_MSI
>  	def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE
>  	depends on PCI && PCI_MSI
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 15f268f646bf..69d2ccb454ef 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -76,6 +76,7 @@ obj-$(CONFIG_MVEBU_GICP)		+= irq-mvebu-gicp.o
>  obj-$(CONFIG_MVEBU_ICU)			+= irq-mvebu-icu.o
>  obj-$(CONFIG_MVEBU_ODMI)		+= irq-mvebu-odmi.o
>  obj-$(CONFIG_MVEBU_PIC)			+= irq-mvebu-pic.o
> +obj-$(CONFIG_MVEBU_SEI)			+= irq-mvebu-sei.o
>  obj-$(CONFIG_LS_SCFG_MSI)		+= irq-ls-scfg-msi.o
>  obj-$(CONFIG_EZNPS_GIC)			+= irq-eznps.o
>  obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-vic.o irq-aspeed-i2c-ic.o
> diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
> new file mode 100644
> index 000000000000..d9abd5e10741
> --- /dev/null
> +++ b/drivers/irqchip/irq-mvebu-sei.c
> @@ -0,0 +1,422 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#define pr_fmt(fmt) "mvebu-sei: " fmt
> +
> +#include <linux/irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/kernel.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/msi.h>
> +#include <linux/platform_device.h>
> +#include <linux/irqchip.h>
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/* Cause register */
> +#define GICP_SECR(idx)		(0x0  + (idx * 0x4))
> +/* Mask register */
> +#define GICP_SEMR(idx)		(0x20 + (idx * 0x4))
> +#define GICP_SET_SEI_OFFSET	0x30
> +
> +#define SEI_IRQ_COUNT_PER_REG	32
> +#define SEI_IRQ_REG_COUNT	2
> +#define SEI_IRQ_COUNT		(SEI_IRQ_COUNT_PER_REG * SEI_IRQ_REG_COUNT)
> +#define SEI_IRQ_REG_IDX(irq_id)	(irq_id / SEI_IRQ_COUNT_PER_REG)
> +#define SEI_IRQ_REG_BIT(irq_id)	(irq_id % SEI_IRQ_COUNT_PER_REG)
> +
> +struct mvebu_sei_interrupt_range {
> +	u32 first;
> +	u32 number;
> +};
> +
> +struct mvebu_sei {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct resource *res;
> +	struct irq_domain *ap_domain;
> +	struct irq_domain *cp_domain;
> +	struct mvebu_sei_interrupt_range ap_interrupts;
> +	struct mvebu_sei_interrupt_range cp_interrupts;
> +	/* Lock on MSI allocations/releases */
> +	spinlock_t cp_msi_lock;
> +	DECLARE_BITMAP(cp_msi_bitmap, SEI_IRQ_COUNT);
> +};
> +
> +static int mvebu_sei_domain_to_sei_irq(struct mvebu_sei *sei,
> +				       struct irq_domain *domain,
> +				       irq_hw_number_t hwirq)
> +{
> +	if (domain == sei->ap_domain)
> +		return sei->ap_interrupts.first + hwirq;
> +	else
> +		return sei->cp_interrupts.first + hwirq;
> +}
> +
> +static void mvebu_sei_reset(struct mvebu_sei *sei)
> +{
> +	u32 reg_idx;
> +
> +	/* Clear IRQ cause registers */
> +	for (reg_idx = 0; reg_idx < SEI_IRQ_REG_COUNT; reg_idx++)
> +		writel(0xFFFFFFFF, sei->base + GICP_SECR(reg_idx));
> +}
> +
> +static void mvebu_sei_mask_irq(struct irq_data *d)
> +{
> +	struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
> +	u32 sei_irq = mvebu_sei_domain_to_sei_irq(sei, d->domain, d->hwirq);
> +	u32 reg_idx = SEI_IRQ_REG_IDX(sei_irq);
> +	u32 reg;
> +
> +	/* 1 disables the interrupt */
> +	reg = readl(sei->base + GICP_SEMR(reg_idx));
> +	reg |= BIT(SEI_IRQ_REG_BIT(sei_irq));
> +	writel(reg, sei->base + GICP_SEMR(reg_idx));
> +}
> +
> +static void mvebu_sei_unmask_irq(struct irq_data *d)
> +{
> +	struct mvebu_sei *sei = irq_data_get_irq_chip_data(d);
> +	u32 sei_irq = mvebu_sei_domain_to_sei_irq(sei, d->domain, d->hwirq);
> +	u32 reg_idx = SEI_IRQ_REG_IDX(sei_irq);
> +	u32 reg;
> +
> +	/* 0 enables the interrupt */
> +	reg = readl(sei->base + GICP_SEMR(reg_idx));
> +	reg &= ~BIT(SEI_IRQ_REG_BIT(sei_irq));
> +	writel(reg, sei->base + GICP_SEMR(reg_idx));
> +}
> +
> +static void mvebu_sei_compose_msi_msg(struct irq_data *data,
> +				      struct msi_msg *msg)
> +{
> +	struct mvebu_sei *sei = data->chip_data;
> +	phys_addr_t set = sei->res->start + GICP_SET_SEI_OFFSET;
> +
> +	msg->data = mvebu_sei_domain_to_sei_irq(sei, data->domain, data->hwirq);
> +	msg->address_lo = lower_32_bits(set);
> +	msg->address_hi = upper_32_bits(set);
> +}
> +
> +static struct irq_chip mvebu_sei_ap_wired_irq_chip = {
> +	.name			= "AP wired SEI",
> +	.irq_mask		= mvebu_sei_mask_irq,
> +	.irq_unmask		= mvebu_sei_unmask_irq,
> +	.irq_eoi		= irq_chip_eoi_parent,
> +	.irq_set_affinity	= irq_chip_set_affinity_parent,
> +	.irq_set_type		= irq_chip_set_type_parent,

You seem to assume that this driver is purely dealing with edge
interrupts. And yet you pass the request directly to the parrent. What
does it mean? Shouldn't you at least check that this is an edge request
and fail otherwise?

> +};
> +
> +static struct irq_chip mvebu_sei_cp_msi_irq_chip = {
> +	.name			= "CP MSI SEI",
> +	.irq_mask		= mvebu_sei_mask_irq,
> +	.irq_unmask		= mvebu_sei_unmask_irq,
> +	.irq_eoi		= irq_chip_eoi_parent,
> +	.irq_set_affinity	= irq_chip_set_affinity_parent,
> +	.irq_set_type		= irq_chip_set_type_parent,

Same here.

> +	.irq_compose_msi_msg	= mvebu_sei_compose_msi_msg,
> +};
> +
> +static int mvebu_sei_irq_domain_alloc(struct irq_domain *domain,
> +				      unsigned int virq, unsigned int nr_irqs,
> +				      void *args)
> +{
> +	struct mvebu_sei *sei = domain->host_data;
> +	struct irq_fwspec *fwspec = args;
> +	struct irq_chip *irq_chip;
> +	int sei_hwirq, hwirq;
> +	int ret;
> +
> +	/* Software only supports single allocations for now */
> +	if (nr_irqs != 1)
> +		return -ENOTSUPP;
> +
> +	if (domain == sei->ap_domain) {

That's not great, really. Pushing the management of the two domains into
the same callbacks is pretty ugly, and makes the code rather confusing.
Is there anything really preventing the two domains from being managed
independently?

> +		irq_chip = &mvebu_sei_ap_wired_irq_chip;
> +		hwirq = fwspec->param[0];
> +	} else {
> +		irq_chip = &mvebu_sei_cp_msi_irq_chip;
> +		spin_lock(&sei->cp_msi_lock);

This could as well be a mutex.

> +		hwirq = bitmap_find_free_region(sei->cp_msi_bitmap,
> +						SEI_IRQ_COUNT, 0);

It is a bit weird that you're allocating from a 64bit bitmap while you
only have 43 interrupts available... At the 44th interrupt, something
bad is going to happen.

> +		spin_unlock(&sei->cp_msi_lock);
> +		if (hwirq < 0)
> +			return -ENOSPC;
> +	}
> +
> +	sei_hwirq = mvebu_sei_domain_to_sei_irq(sei, domain, hwirq);

Splitting the callbacks would definitely avoid that kind of horror.

> +
> +	fwspec->fwnode = domain->parent->fwnode;
> +	fwspec->param_count = 3;
> +	fwspec->param[0] = GIC_SPI;
> +	fwspec->param[1] = sei_hwirq;
> +	fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
> +
> +	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, fwspec);
> +	if (ret)
> +		goto release_region;
> +
> +	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, irq_chip, sei);
> +	if (ret)
> +		goto free_irq_parents;
> +
> +	return 0;
> +
> +free_irq_parents:
> +	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
> +release_region:
> +	if (domain == sei->cp_domain) {
> +		spin_lock(&sei->cp_msi_lock);
> +		bitmap_release_region(sei->cp_msi_bitmap, hwirq, 0);
> +		spin_unlock(&sei->cp_msi_lock);
> +	}
> +
> +	return ret;
> +}
> +
> +static void mvebu_sei_irq_domain_free(struct irq_domain *domain,
> +				      unsigned int virq, unsigned int nr_irqs)
> +{
> +	struct mvebu_sei *sei = domain->host_data;
> +	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> +	u32 irq_nb = sei->ap_interrupts.number + sei->cp_interrupts.number;
> +
> +	if (nr_irqs != 1 || d->hwirq >= irq_nb) {
> +		dev_err(sei->dev, "Invalid hwirq %lu\n", d->hwirq);
> +		return;
> +	}
> +
> +	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
> +
> +	spin_lock(&sei->cp_msi_lock);
> +	bitmap_release_region(sei->cp_msi_bitmap, d->hwirq, 0);
> +	spin_unlock(&sei->cp_msi_lock);
> +}
> +
> +static const struct irq_domain_ops mvebu_sei_ap_domain_ops = {
> +	.xlate = irq_domain_xlate_onecell,
> +	.alloc = mvebu_sei_irq_domain_alloc,
> +	.free = mvebu_sei_irq_domain_free,
> +};
> +
> +static const struct irq_domain_ops mvebu_sei_cp_domain_ops = {
> +	.alloc = mvebu_sei_irq_domain_alloc,
> +	.free = mvebu_sei_irq_domain_free,
> +};
> +
> +static struct irq_chip mvebu_sei_msi_irq_chip = {
> +	.name		= "SEI",
> +	.irq_set_type	= irq_chip_set_type_parent,

Same question here.

> +};
> +
> +static struct msi_domain_ops mvebu_sei_msi_ops = {
> +};
> +
> +static struct msi_domain_info mvebu_sei_msi_domain_info = {
> +	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS,
> +	.ops	= &mvebu_sei_msi_ops,
> +	.chip	= &mvebu_sei_msi_irq_chip,
> +};
> +
> +static void mvebu_sei_handle_cascade_irq(struct irq_desc *desc)
> +{
> +	struct mvebu_sei *sei = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	unsigned long irqmap, irq_bit;
> +	u32 reg_idx, virq, irqn;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	/* Read both SEI cause registers (64 bits) */
> +	for (reg_idx = 0; reg_idx < SEI_IRQ_REG_COUNT; reg_idx++) {
> +		irqmap = readl_relaxed(sei->base + GICP_SECR(reg_idx));
> +
> +		/* Call handler for each set bit */
> +		for_each_set_bit(irq_bit, &irqmap, SEI_IRQ_COUNT_PER_REG) {
> +			/* Cause Register gives the SEI number */
> +			irqn = irq_bit + reg_idx * SEI_IRQ_COUNT_PER_REG;
> +			/*
> +			 * Finding Linux mapping (virq) needs the right domain
> +			 * and the relative hwirq (which start at 0 in both
> +			 * cases, while irqn is relative to all SEI interrupts).
> +			 */

It is a bit odd that you're virtualizing the hwirq number. The whole
point of splitting hwirq from virq is that you don't have to do that and
can use the the raw HW number. You're saving a tiny bit of memory in the
irq_domain, at the expense of more complexity. I don't know if that's
worth it...

> +			if (irqn < sei->ap_interrupts.number) {
> +				virq = irq_find_mapping(sei->ap_domain, irqn);
> +			} else {
> +				irqn -= sei->ap_interrupts.number;
> +				virq = irq_find_mapping(sei->cp_domain, irqn);
> +			}
> +
> +			/* Call IRQ handler */
> +			generic_handle_irq(virq);
> +		}
> +
> +		/* Clear interrupt indication by writing 1 to it */
> +		writel(irqmap, sei->base + GICP_SECR(reg_idx));
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static int mvebu_sei_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node, *parent, *child;
> +	struct irq_domain *parent_domain, *plat_domain;
> +	struct mvebu_sei *sei;
> +	const __be32 *property;
> +	u32 parent_irq, size;
> +	int ret;
> +
> +	sei = devm_kzalloc(&pdev->dev, sizeof(*sei), GFP_KERNEL);
> +	if (!sei)
> +		return -ENOMEM;
> +
> +	sei->dev = &pdev->dev;
> +
> +	spin_lock_init(&sei->cp_msi_lock);
> +
> +	sei->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	sei->base = devm_ioremap_resource(sei->dev, sei->res);
> +	if (!sei->base) {
> +		dev_err(sei->dev, "Failed to remap SEI resource\n");
> +		return -ENODEV;
> +	}
> +
> +	mvebu_sei_reset(sei);
> +
> +	/*
> +	 * Reserve the single (top-level) parent SPI IRQ from which all the
> +	 * interrupts handled by this driver will be signaled.
> +	 */
> +	parent_irq = irq_of_parse_and_map(node, 0);
> +	if (parent_irq <= 0) {
> +		dev_err(sei->dev, "Failed to retrieve top-level SPI IRQ\n");
> +		return -ENODEV;
> +	}
> +
> +	irq_set_chained_handler(parent_irq, mvebu_sei_handle_cascade_irq);
> +	irq_set_handler_data(parent_irq, sei);
> +
> +	/*
> +	 * SEIs in the range [ 0; 20] are wired and come from the AP.
> +	 * SEIs in the range [21; 63] are CP SEI and are triggered through MSIs.
> +	 *
> +	 * Each SEI 'domain' is represented as a subnode.
> +	 */
> +
> +	/* Get a reference to the parent domain to create a hierarchy */
> +	parent = of_irq_find_parent(node);
> +	if (!parent) {
> +		dev_err(sei->dev, "Failed to find parent IRQ node\n");
> +		ret = -ENODEV;
> +		goto dispose_irq;
> +	}
> +
> +	parent_domain = irq_find_host(parent);
> +	if (!parent_domain) {
> +		dev_err(sei->dev, "Failed to find parent IRQ domain\n");
> +		ret = -ENODEV;
> +		goto dispose_irq;
> +	}
> +
> +	/* Create the 'wired' hierarchy */
> +	child = of_find_node_by_name(node, "sei-wired-controller");
> +	if (!child) {
> +		dev_err(sei->dev, "Missing 'sei-wired-controller' subnode\n");
> +		ret = -ENODEV;
> +		goto dispose_irq;
> +	}
> +
> +	property = of_get_property(child, "marvell,sei-ranges", &size);
> +	if (!property || size != (2 * sizeof(u32))) {
> +		dev_err(sei->dev, "Missing 'marvell,sei-ranges' property\n");
> +		of_node_put(child);
> +		ret = -ENODEV;
> +		goto dispose_irq;
> +	}
> +
> +	sei->ap_interrupts.first = be32_to_cpu(property[0]);
> +	sei->ap_interrupts.number = be32_to_cpu(property[1]);
> +	sei->ap_domain = irq_domain_create_hierarchy(parent_domain, 0,
> +						     sei->ap_interrupts.number,
> +						     of_node_to_fwnode(child),
> +						     &mvebu_sei_ap_domain_ops,
> +						     sei);
> +	of_node_put(child);
> +	if (!sei->ap_domain) {
> +		dev_err(sei->dev, "Failed to create AP IRQ domain\n");
> +		ret = -ENOMEM;
> +		goto dispose_irq;
> +	}
> +
> +	/* Create the 'MSI' hierarchy */
> +	child = of_find_node_by_name(node, "sei-msi-controller");
> +	if (!child) {
> +		dev_err(sei->dev, "Missing 'sei-msi-controller' subnode\n");
> +		ret = -ENODEV;
> +		goto remove_ap_domain;
> +	}
> +
> +	property = of_get_property(child, "marvell,sei-ranges", &size);
> +	if (!property || size != (2 * sizeof(u32))) {
> +		dev_err(sei->dev, "Missing 'marvell,sei-ranges' property\n");
> +		of_node_put(child);
> +		ret = -ENODEV;
> +		goto remove_ap_domain;
> +	}
> +
> +	sei->cp_interrupts.first = be32_to_cpu(property[0]);
> +	sei->cp_interrupts.number = be32_to_cpu(property[1]);
> +	sei->cp_domain = irq_domain_create_hierarchy(parent_domain, 0,
> +						     sei->cp_interrupts.number,
> +						     of_node_to_fwnode(child),
> +						     &mvebu_sei_cp_domain_ops,
> +						     sei);
> +	if (!sei->cp_domain) {
> +		pr_err("Failed to create CPs IRQ domain\n");
> +		of_node_put(child);
> +		ret = -ENOMEM;
> +		goto remove_ap_domain;
> +	}
> +
> +	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(child),
> +						     &mvebu_sei_msi_domain_info,
> +						     sei->cp_domain);
> +	of_node_put(child);
> +	if (!plat_domain) {
> +		pr_err("Failed to create CPs MSI domain\n");
> +		ret = -ENOMEM;
> +		goto remove_cp_domain;
> +	}
> +
> +	platform_set_drvdata(pdev, sei);
> +
> +	return 0;
> +
> +remove_cp_domain:
> +	irq_domain_remove(sei->cp_domain);
> +remove_ap_domain:
> +	irq_domain_remove(sei->ap_domain);
> +dispose_irq:
> +	irq_dispose_mapping(parent_irq);
> +
> +	return ret;
> +}
> +
> +static const struct of_device_id mvebu_sei_of_match[] = {
> +	{ .compatible = "marvell,armada-8k-sei", },
> +	{},
> +};
> +
> +static struct platform_driver mvebu_sei_driver = {
> +	.probe  = mvebu_sei_probe,
> +	.driver = {
> +		.name = "mvebu-sei",
> +		.of_match_table = mvebu_sei_of_match,
> +	},
> +};
> +builtin_platform_driver(mvebu_sei_driver);
> 

It feels like this patch could do with a total split:

- Introduce the wired side of the driver
- then the MSI part

Drop the common domain callbacks, and treat the two domains separately.
I seriously doubt there will be much of an overlap anyway.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* Re: [PATCH RFC 00/24] Lima DRM driver
From: Christian König @ 2018-05-23 13:59 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
	Neil Armstrong, Andrei Paulau, dri-devel, Vasily Khoruzhick,
	Erico Nunes
In-Reply-To: <CAKGbVbsMftEyOv6bh2g-yebj1+yO+BNJ=j1yJzgjwkM59wFz5w@mail.gmail.com>

Am 23.05.2018 um 15:52 schrieb Qiang Yu:
> On Wed, May 23, 2018 at 5:29 PM, Christian König
> <ckoenig.leichtzumerken@gmail.com> wrote:
>> Am 18.05.2018 um 11:27 schrieb Qiang Yu:
>>> Kernel DRM driver for ARM Mali 400/450 GPUs.
>>>
>>> This implementation mainly take amdgpu DRM driver as reference.
>>>
>>> - Mali 4xx GPUs have two kinds of processors GP and PP. GP is for
>>>     OpenGL vertex shader processing and PP is for fragment shader
>>>     processing. Each processor has its own MMU so prcessors work in
>>>     virtual address space.
>>> - There's only one GP but multiple PP (max 4 for mali 400 and 8
>>>     for mali 450) in the same mali 4xx GPU. All PPs are grouped
>>>     togather to handle a single fragment shader task divided by
>>>     FB output tiled pixels. Mali 400 user space driver is
>>>     responsible for assign target tiled pixels to each PP, but mali
>>>     450 has a HW module called DLBU to dynamically balance each
>>>     PP's load.
>>> - User space driver allocate buffer object and map into GPU
>>>     virtual address space, upload command stream and draw data with
>>>     CPU mmap of the buffer object, then submit task to GP/PP with
>>>     a register frame indicating where is the command stream and misc
>>>     settings.
>>> - There's no command stream validation/relocation due to each user
>>>     process has its own GPU virtual address space. GP/PP's MMU switch
>>>     virtual address space before running two tasks from different
>>>     user process. Error or evil user space code just get MMU fault
>>>     or GP/PP error IRQ, then the HW/SW will be recovered.
>>> - Use TTM as MM. TTM_PL_TT type memory is used as the content of
>>>     lima buffer object which is allocated from TTM page pool. all
>>>     lima buffer object gets pinned with TTM_PL_FLAG_NO_EVICT when
>>>     allocation, so there's no buffer eviction and swap for now. We
>>>     need reverse engineering to see if and how GP/PP support MMU
>>>     fault recovery (continue execution). Otherwise we have to
>>>     pin/unpin each envolved buffer when task creation/deletion.
>>
>> Well pinning all memory is usually a no-go for upstreaming. But since you
>> are already using the drm_sched for GPU task scheduling why are you actually
>> needing this?
>>
>> The scheduler should take care of signaling all fences when the hardware is
>> done with it's magic and that is enough for TTM to note that a buffer object
>> is movable again (e.g. unpin them).
> Please correct me if I'm wrong.

Well, you are wrong :)

> One way to implement eviction/swap is like this:
> call validation on each buffers involved in a task, but this won't
> prevent it from
> eviction/swap when executing, so a GPU MMU fault may happen and in the
> handler we need to recover the buffer evicted/swapped.
>
> Another way is pin/unpin buffers evolved when task create/free.
>
> First way is better when memory load is low and second way is better when
> memory load is high. First way also need less memory.
>
> So I'd prefer first way but due to the GPU MMU fault
> HW op need reverse engineering, I have to pin all buffers now. After
> the HW op is clear, I can choose one way to implement.

The general approach is:
1.) Lock all BOs
2.) Validate all BOs
3.) Add the fence
4.) Unlock the BOs

BOs can't be evicted while they are locked and since you already add the 
fence that should be perfectly sufficient to prevent it from being 
evicted until your operation is completed.

Using the MMU is certainly be better in general, but usually only 
optional and a pain in the ass to get working. We have that in amdgpu 
for quite a while as well now and still don't use it because of that.

Regards,
Christian.

>
> Regards,
> Qiang
>
>> Christian.
>>
>>
>>> - Use drm_sched for GPU task schedule. Each OpenGL context should
>>>     have a lima context object in the kernel to distinguish tasks
>>>     from different user. drm_sched gets task from each lima context
>>>     in a fair way.
>>>
>>> Not implemented:
>>> - Dump buffer support
>>> - Power management
>>> - Performance counter
>>>
>>> This patch serial just pack a pair of .c/.h files in each patch.
>>> For whole history of this driver's development, see:
>>> https://github.com/yuq/linux-lima/commits/lima-4.17-rc4
>>>
>>> Mesa driver is still in development and not ready for daily usage,
>>> but can run some simple tests like kmscube and glamrk2, see:
>>> https://github.com/yuq/mesa-lima
>>>
>>> Andrei Paulau (1):
>>>     arm64/dts: add switch-delay for meson mali
>>>
>>> Lima Project Developers (10):
>>>     drm/lima: add mali 4xx GPU hardware regs
>>>     drm/lima: add lima core driver
>>>     drm/lima: add GPU device functions
>>>     drm/lima: add PMU related functions
>>>     drm/lima: add PP related functions
>>>     drm/lima: add MMU related functions
>>>     drm/lima: add GPU virtual memory space handing
>>>     drm/lima: add GEM related functions
>>>     drm/lima: add GEM Prime related functions
>>>     drm/lima: add makefile and kconfig
>>>
>>> Qiang Yu (12):
>>>     dt-bindings: add switch-delay property for mali-utgard
>>>     arm64/dts: add switch-delay for meson mali
>>>     Revert "drm: Nerf the preclose callback for modern drivers"
>>>     drm/lima: add lima uapi header
>>>     drm/lima: add L2 cache functions
>>>     drm/lima: add GP related functions
>>>     drm/lima: add BCAST related function
>>>     drm/lima: add DLBU related functions
>>>     drm/lima: add TTM subsystem functions
>>>     drm/lima: add buffer object functions
>>>     drm/lima: add GPU schedule using DRM_SCHED
>>>     drm/lima: add context related functions
>>>
>>> Simon Shields (1):
>>>     ARM: dts: add gpu node to exynos4
>>>
>>>    .../bindings/gpu/arm,mali-utgard.txt          |   4 +
>>>    arch/arm/boot/dts/exynos4.dtsi                |  33 ++
>>>    arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi   |   1 +
>>>    .../boot/dts/amlogic/meson-gxl-mali.dtsi      |   1 +
>>>    drivers/gpu/drm/Kconfig                       |   2 +
>>>    drivers/gpu/drm/Makefile                      |   1 +
>>>    drivers/gpu/drm/drm_file.c                    |   8 +-
>>>    drivers/gpu/drm/lima/Kconfig                  |   9 +
>>>    drivers/gpu/drm/lima/Makefile                 |  19 +
>>>    drivers/gpu/drm/lima/lima_bcast.c             |  65 +++
>>>    drivers/gpu/drm/lima/lima_bcast.h             |  34 ++
>>>    drivers/gpu/drm/lima/lima_ctx.c               | 143 +++++
>>>    drivers/gpu/drm/lima/lima_ctx.h               |  51 ++
>>>    drivers/gpu/drm/lima/lima_device.c            | 407 ++++++++++++++
>>>    drivers/gpu/drm/lima/lima_device.h            | 136 +++++
>>>    drivers/gpu/drm/lima/lima_dlbu.c              |  75 +++
>>>    drivers/gpu/drm/lima/lima_dlbu.h              |  37 ++
>>>    drivers/gpu/drm/lima/lima_drv.c               | 466 ++++++++++++++++
>>>    drivers/gpu/drm/lima/lima_drv.h               |  77 +++
>>>    drivers/gpu/drm/lima/lima_gem.c               | 459 ++++++++++++++++
>>>    drivers/gpu/drm/lima/lima_gem.h               |  41 ++
>>>    drivers/gpu/drm/lima/lima_gem_prime.c         |  66 +++
>>>    drivers/gpu/drm/lima/lima_gem_prime.h         |  31 ++
>>>    drivers/gpu/drm/lima/lima_gp.c                | 293 +++++++++++
>>>    drivers/gpu/drm/lima/lima_gp.h                |  34 ++
>>>    drivers/gpu/drm/lima/lima_l2_cache.c          |  98 ++++
>>>    drivers/gpu/drm/lima/lima_l2_cache.h          |  32 ++
>>>    drivers/gpu/drm/lima/lima_mmu.c               | 154 ++++++
>>>    drivers/gpu/drm/lima/lima_mmu.h               |  34 ++
>>>    drivers/gpu/drm/lima/lima_object.c            | 120 +++++
>>>    drivers/gpu/drm/lima/lima_object.h            |  87 +++
>>>    drivers/gpu/drm/lima/lima_pmu.c               |  85 +++
>>>    drivers/gpu/drm/lima/lima_pmu.h               |  30 ++
>>>    drivers/gpu/drm/lima/lima_pp.c                | 418 +++++++++++++++
>>>    drivers/gpu/drm/lima/lima_pp.h                |  37 ++
>>>    drivers/gpu/drm/lima/lima_regs.h              | 304 +++++++++++
>>>    drivers/gpu/drm/lima/lima_sched.c             | 497 ++++++++++++++++++
>>>    drivers/gpu/drm/lima/lima_sched.h             | 126 +++++
>>>    drivers/gpu/drm/lima/lima_ttm.c               | 409 ++++++++++++++
>>>    drivers/gpu/drm/lima/lima_ttm.h               |  44 ++
>>>    drivers/gpu/drm/lima/lima_vm.c                | 312 +++++++++++
>>>    drivers/gpu/drm/lima/lima_vm.h                |  73 +++
>>>    include/drm/drm_drv.h                         |  23 +-
>>>    include/uapi/drm/lima_drm.h                   | 195 +++++++
>>>    44 files changed, 5565 insertions(+), 6 deletions(-)
>>>    create mode 100644 drivers/gpu/drm/lima/Kconfig
>>>    create mode 100644 drivers/gpu/drm/lima/Makefile
>>>    create mode 100644 drivers/gpu/drm/lima/lima_bcast.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_bcast.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_ctx.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_ctx.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_device.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_device.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_drv.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_drv.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gem.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gem.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gp.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_gp.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_mmu.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_object.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_object.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_pmu.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_pmu.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_pp.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_pp.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_regs.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_sched.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_sched.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_ttm.h
>>>    create mode 100644 drivers/gpu/drm/lima/lima_vm.c
>>>    create mode 100644 drivers/gpu/drm/lima/lima_vm.h
>>>    create mode 100644 include/uapi/drm/lima_drm.h
>>>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH] ARM: DTS: imx53: Add support for imx53 HSC/DDC boards from K+P
From: Fabio Estevam @ 2018-05-23 13:56 UTC (permalink / raw)
  To: Lukasz Majewski
  Cc: Rob Herring, Mark Rutland, Russell King, Shawn Guo, Sascha Hauer,
	Fabio Estevam, linux-kernel,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20180519140202.3449e3c1@jawa>

Hi Lukasz,

On Sat, May 19, 2018 at 9:02 AM, Lukasz Majewski <lukma@denx.de> wrote:

> After removing imx53-kp-ddc and imx53-kp-common iomux subnodes I do see
> following errors in the dmesg (v4.17-rc5):
>
> imx53-pinctrl 53fa8000.iomuxc: function 'iomuxc' not supported
> imx53-pinctrl 53fa8000.iomuxc: invalid function iomuxc in map table

Could you please investigate this error?

I have just tried the following change on a imx53-qsb:
http://code.bulix.org/ik01yu-339697

and it works as expected:
# dmesg  | grep iomux
[    0.100046] imx53-pinctrl 53fa8000.iomuxc: initialized IMX pinctrl driver

^ permalink raw reply

* Re: [PATCH v11 0/2] Kryo CPU scaling driver
From: Sudeep Holla @ 2018-05-23 13:54 UTC (permalink / raw)
  To: Ilia Lin, vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm,
	devicetree, linux-kernel
  Cc: Sudeep Holla
In-Reply-To: <1527079139-3558-1-git-send-email-ilialin@codeaurora.org>



On 23/05/18 13:38, Ilia Lin wrote:
> [v11]
>  * Addressed comment from Russel about device_node reference
>  * Addressed comment from Sudeep about the late_initcall
>  * Transformed init into probe to take care of deferals
> 
> [v10]
>  * Split the series into domains
>  * Addressed comments from Viresh and Sudeep about logical CPU numbering.
> 
> The qcom-cpufreq-kryo driver is aimed to support different SOC versions.
> The driver reads eFuse information and chooses the required OPP subset
> by passing the OPP supported-hw parameter.
> 
> The series depends on the series from Viresh:
> https://patchwork.kernel.org/patch/10418139/
> 
> The previous spin was here:
> https://patchwork.kernel.org/patch/10420809/
> 

IIUC, this depends on "CPU scaling support for msm8996" [1] for
the functionality though the change is independent ?

-- 
Regards,
Sudeep

[1] https://www.spinics.net/lists/arm-kernel/msg654978.html

^ permalink raw reply

* Re: [PATCH RFC 00/24] Lima DRM driver
From: Qiang Yu @ 2018-05-23 13:52 UTC (permalink / raw)
  To: christian.koenig
  Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
	Neil Armstrong, Andrei Paulau, dri-devel, Vasily Khoruzhick,
	Erico Nunes
In-Reply-To: <940a5ee5-ff3e-e438-504e-f720f201fee6@gmail.com>

On Wed, May 23, 2018 at 5:29 PM, Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
> Am 18.05.2018 um 11:27 schrieb Qiang Yu:
>>
>> Kernel DRM driver for ARM Mali 400/450 GPUs.
>>
>> This implementation mainly take amdgpu DRM driver as reference.
>>
>> - Mali 4xx GPUs have two kinds of processors GP and PP. GP is for
>>    OpenGL vertex shader processing and PP is for fragment shader
>>    processing. Each processor has its own MMU so prcessors work in
>>    virtual address space.
>> - There's only one GP but multiple PP (max 4 for mali 400 and 8
>>    for mali 450) in the same mali 4xx GPU. All PPs are grouped
>>    togather to handle a single fragment shader task divided by
>>    FB output tiled pixels. Mali 400 user space driver is
>>    responsible for assign target tiled pixels to each PP, but mali
>>    450 has a HW module called DLBU to dynamically balance each
>>    PP's load.
>> - User space driver allocate buffer object and map into GPU
>>    virtual address space, upload command stream and draw data with
>>    CPU mmap of the buffer object, then submit task to GP/PP with
>>    a register frame indicating where is the command stream and misc
>>    settings.
>> - There's no command stream validation/relocation due to each user
>>    process has its own GPU virtual address space. GP/PP's MMU switch
>>    virtual address space before running two tasks from different
>>    user process. Error or evil user space code just get MMU fault
>>    or GP/PP error IRQ, then the HW/SW will be recovered.
>> - Use TTM as MM. TTM_PL_TT type memory is used as the content of
>>    lima buffer object which is allocated from TTM page pool. all
>>    lima buffer object gets pinned with TTM_PL_FLAG_NO_EVICT when
>>    allocation, so there's no buffer eviction and swap for now. We
>>    need reverse engineering to see if and how GP/PP support MMU
>>    fault recovery (continue execution). Otherwise we have to
>>    pin/unpin each envolved buffer when task creation/deletion.
>
>
> Well pinning all memory is usually a no-go for upstreaming. But since you
> are already using the drm_sched for GPU task scheduling why are you actually
> needing this?
>
> The scheduler should take care of signaling all fences when the hardware is
> done with it's magic and that is enough for TTM to note that a buffer object
> is movable again (e.g. unpin them).

Please correct me if I'm wrong.

One way to implement eviction/swap is like this:
call validation on each buffers involved in a task, but this won't
prevent it from
eviction/swap when executing, so a GPU MMU fault may happen and in the
handler we need to recover the buffer evicted/swapped.

Another way is pin/unpin buffers evolved when task create/free.

First way is better when memory load is low and second way is better when
memory load is high. First way also need less memory.

So I'd prefer first way but due to the GPU MMU fault
HW op need reverse engineering, I have to pin all buffers now. After
the HW op is clear, I can choose one way to implement.

Regards,
Qiang

>
> Christian.
>
>
>> - Use drm_sched for GPU task schedule. Each OpenGL context should
>>    have a lima context object in the kernel to distinguish tasks
>>    from different user. drm_sched gets task from each lima context
>>    in a fair way.
>>
>> Not implemented:
>> - Dump buffer support
>> - Power management
>> - Performance counter
>>
>> This patch serial just pack a pair of .c/.h files in each patch.
>> For whole history of this driver's development, see:
>> https://github.com/yuq/linux-lima/commits/lima-4.17-rc4
>>
>> Mesa driver is still in development and not ready for daily usage,
>> but can run some simple tests like kmscube and glamrk2, see:
>> https://github.com/yuq/mesa-lima
>>
>> Andrei Paulau (1):
>>    arm64/dts: add switch-delay for meson mali
>>
>> Lima Project Developers (10):
>>    drm/lima: add mali 4xx GPU hardware regs
>>    drm/lima: add lima core driver
>>    drm/lima: add GPU device functions
>>    drm/lima: add PMU related functions
>>    drm/lima: add PP related functions
>>    drm/lima: add MMU related functions
>>    drm/lima: add GPU virtual memory space handing
>>    drm/lima: add GEM related functions
>>    drm/lima: add GEM Prime related functions
>>    drm/lima: add makefile and kconfig
>>
>> Qiang Yu (12):
>>    dt-bindings: add switch-delay property for mali-utgard
>>    arm64/dts: add switch-delay for meson mali
>>    Revert "drm: Nerf the preclose callback for modern drivers"
>>    drm/lima: add lima uapi header
>>    drm/lima: add L2 cache functions
>>    drm/lima: add GP related functions
>>    drm/lima: add BCAST related function
>>    drm/lima: add DLBU related functions
>>    drm/lima: add TTM subsystem functions
>>    drm/lima: add buffer object functions
>>    drm/lima: add GPU schedule using DRM_SCHED
>>    drm/lima: add context related functions
>>
>> Simon Shields (1):
>>    ARM: dts: add gpu node to exynos4
>>
>>   .../bindings/gpu/arm,mali-utgard.txt          |   4 +
>>   arch/arm/boot/dts/exynos4.dtsi                |  33 ++
>>   arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi   |   1 +
>>   .../boot/dts/amlogic/meson-gxl-mali.dtsi      |   1 +
>>   drivers/gpu/drm/Kconfig                       |   2 +
>>   drivers/gpu/drm/Makefile                      |   1 +
>>   drivers/gpu/drm/drm_file.c                    |   8 +-
>>   drivers/gpu/drm/lima/Kconfig                  |   9 +
>>   drivers/gpu/drm/lima/Makefile                 |  19 +
>>   drivers/gpu/drm/lima/lima_bcast.c             |  65 +++
>>   drivers/gpu/drm/lima/lima_bcast.h             |  34 ++
>>   drivers/gpu/drm/lima/lima_ctx.c               | 143 +++++
>>   drivers/gpu/drm/lima/lima_ctx.h               |  51 ++
>>   drivers/gpu/drm/lima/lima_device.c            | 407 ++++++++++++++
>>   drivers/gpu/drm/lima/lima_device.h            | 136 +++++
>>   drivers/gpu/drm/lima/lima_dlbu.c              |  75 +++
>>   drivers/gpu/drm/lima/lima_dlbu.h              |  37 ++
>>   drivers/gpu/drm/lima/lima_drv.c               | 466 ++++++++++++++++
>>   drivers/gpu/drm/lima/lima_drv.h               |  77 +++
>>   drivers/gpu/drm/lima/lima_gem.c               | 459 ++++++++++++++++
>>   drivers/gpu/drm/lima/lima_gem.h               |  41 ++
>>   drivers/gpu/drm/lima/lima_gem_prime.c         |  66 +++
>>   drivers/gpu/drm/lima/lima_gem_prime.h         |  31 ++
>>   drivers/gpu/drm/lima/lima_gp.c                | 293 +++++++++++
>>   drivers/gpu/drm/lima/lima_gp.h                |  34 ++
>>   drivers/gpu/drm/lima/lima_l2_cache.c          |  98 ++++
>>   drivers/gpu/drm/lima/lima_l2_cache.h          |  32 ++
>>   drivers/gpu/drm/lima/lima_mmu.c               | 154 ++++++
>>   drivers/gpu/drm/lima/lima_mmu.h               |  34 ++
>>   drivers/gpu/drm/lima/lima_object.c            | 120 +++++
>>   drivers/gpu/drm/lima/lima_object.h            |  87 +++
>>   drivers/gpu/drm/lima/lima_pmu.c               |  85 +++
>>   drivers/gpu/drm/lima/lima_pmu.h               |  30 ++
>>   drivers/gpu/drm/lima/lima_pp.c                | 418 +++++++++++++++
>>   drivers/gpu/drm/lima/lima_pp.h                |  37 ++
>>   drivers/gpu/drm/lima/lima_regs.h              | 304 +++++++++++
>>   drivers/gpu/drm/lima/lima_sched.c             | 497 ++++++++++++++++++
>>   drivers/gpu/drm/lima/lima_sched.h             | 126 +++++
>>   drivers/gpu/drm/lima/lima_ttm.c               | 409 ++++++++++++++
>>   drivers/gpu/drm/lima/lima_ttm.h               |  44 ++
>>   drivers/gpu/drm/lima/lima_vm.c                | 312 +++++++++++
>>   drivers/gpu/drm/lima/lima_vm.h                |  73 +++
>>   include/drm/drm_drv.h                         |  23 +-
>>   include/uapi/drm/lima_drm.h                   | 195 +++++++
>>   44 files changed, 5565 insertions(+), 6 deletions(-)
>>   create mode 100644 drivers/gpu/drm/lima/Kconfig
>>   create mode 100644 drivers/gpu/drm/lima/Makefile
>>   create mode 100644 drivers/gpu/drm/lima/lima_bcast.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_bcast.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_ctx.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_ctx.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_device.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_device.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_drv.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_drv.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_gem.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_gem.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_gp.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_gp.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_mmu.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_object.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_object.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_pmu.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_pmu.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_pp.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_pp.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_regs.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_sched.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_sched.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_ttm.h
>>   create mode 100644 drivers/gpu/drm/lima/lima_vm.c
>>   create mode 100644 drivers/gpu/drm/lima/lima_vm.h
>>   create mode 100644 include/uapi/drm/lima_drm.h
>>
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v11 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver
From: Sudeep Holla @ 2018-05-23 13:51 UTC (permalink / raw)
  To: Ilia Lin, mturquette, sboyd, robh, mark.rutland, andy.gross,
	david.brown, will.deacon
  Cc: Sudeep Holla, devicetree, linux-arm-msm, linux-kernel, vireshk,
	linux-soc, linux-clk, linux-arm-kernel
In-Reply-To: <1527079981-11179-2-git-send-email-ilialin@codeaurora.org>



On 23/05/18 13:52, Ilia Lin wrote:
> 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/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
> +

I think kbuild bot complained about this and you haven't addressed it.
This can be enabled on ARM and build breaks due to missing sysreg.h
IIRC. Look at the kbuild report and fix it.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH RFC 05/24] Revert "drm: Nerf the preclose callback for modern drivers"
From: Christian König @ 2018-05-23 13:41 UTC (permalink / raw)
  To: Qiang Yu
  Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
	Neil Armstrong, Andrei Paulau, dri-devel, Vasily Khoruzhick,
	Erico Nunes
In-Reply-To: <CAKGbVbuSuAEF9Zd_usM5ika5KuFiY75jCG3gwOfeAExSciRV7Q@mail.gmail.com>

Am 23.05.2018 um 15:13 schrieb Qiang Yu:
> On Wed, May 23, 2018 at 5:35 PM, Christian König
> <ckoenig.leichtzumerken@gmail.com> wrote:
>> Well NAK, that brings back a callback we worked quite hard on getting rid
>> of.
>>
>> It looks like the problem isn't that you need the preclose callback, but you
>> rather seem to misunderstood how TTM works.
>>
>> All you need to do is to cleanup your command submission path so that the
>> caller of lima_sched_context_queue_task() adds the resulting scheduler fence
>> to TTMs buffer objects.
> You mean adding the finished dma fence to the buffer's reservation object then
> waiting it before unmap the buffer from GPU VM in the drm_release()'s buffer
> close callback?

That is one possibility, but also not necessary.

TTM has a destroy callback which is called from a workqueue when all 
fences on that BOs have signaled.

Depending on your VM management you can use it to delay unmapping the 
buffer until it is actually not used any more.

> Adding fence is done already, and I did wait it before unmap. But then
> I see when
> the buffer is shared between processes, the "perfect wait" is just
> wait the fence
> from this process's task, so it's better to also distinguish fences.
> If so, I just think
> why we don't just wait tasks from this process in the preclose before unmap/free
> buffer in the drm_release()?

Well it depends on your VM management. When userspace expects that the 
VM space the BO used is reusable immediately than the TTM callback won't 
work.

On the other hand you can just grab the list of fences on a BO and 
filter out the ones from your current process and wait for those. See 
amdgpu_sync_resv() as an example how to do that.

Christian.

>
> Regards,
> Qiang
>
>>
>> Am 18.05.2018 um 11:27 schrieb Qiang Yu:
>>> This reverts commit 45c3d213a400c952ab7119f394c5293bb6877e6b.
>>>
>>> lima driver need preclose to wait all task in the context
>>> created within closing file to finish before free all the
>>> buffer object. Otherwise pending tesk may fail and get
>>> noisy MMU fault message.
>>>
>>> Move this wait to each buffer object free function can
>>> achieve the same result but some buffer object is shared
>>> with other file context, but we only want to wait the
>>> closing file context's tasks. So the implementation is
>>> not that straight forword compared to the preclose one.
>>>
>>> Signed-off-by: Qiang Yu <yuq825@gmail.com>
>>> ---
>>>    drivers/gpu/drm/drm_file.c |  8 ++++----
>>>    include/drm/drm_drv.h      | 23 +++++++++++++++++++++--
>>>    2 files changed, 25 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
>>> index e394799979a6..0a43107396b9 100644
>>> --- a/drivers/gpu/drm/drm_file.c
>>> +++ b/drivers/gpu/drm/drm_file.c
>>> @@ -361,8 +361,9 @@ void drm_lastclose(struct drm_device * dev)
>>>     *
>>>     * This function must be used by drivers as their
>>> &file_operations.release
>>>     * method. It frees any resources associated with the open file, and
>>> calls the
>>> - * &drm_driver.postclose driver callback. If this is the last open file
>>> for the
>>> - * DRM device also proceeds to call the &drm_driver.lastclose driver
>>> callback.
>>> + * &drm_driver.preclose and &drm_driver.lastclose driver callbacks. If
>>> this is
>>> + * the last open file for the DRM device also proceeds to call the
>>> + * &drm_driver.lastclose driver callback.
>>>     *
>>>     * RETURNS:
>>>     *
>>> @@ -382,8 +383,7 @@ int drm_release(struct inode *inode, struct file
>>> *filp)
>>>          list_del(&file_priv->lhead);
>>>          mutex_unlock(&dev->filelist_mutex);
>>>    -     if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
>>> -           dev->driver->preclose)
>>> +       if (dev->driver->preclose)
>>>                  dev->driver->preclose(dev, file_priv);
>>>          /* ========================================================
>>> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
>>> index d23dcdd1bd95..8d6080f97ed4 100644
>>> --- a/include/drm/drm_drv.h
>>> +++ b/include/drm/drm_drv.h
>>> @@ -107,6 +107,23 @@ struct drm_driver {
>>>           */
>>>          int (*open) (struct drm_device *, struct drm_file *);
>>>    +     /**
>>> +        * @preclose:
>>> +        *
>>> +        * One of the driver callbacks when a new &struct drm_file is
>>> closed.
>>> +        * Useful for tearing down driver-private data structures
>>> allocated in
>>> +        * @open like buffer allocators, execution contexts or similar
>>> things.
>>> +        *
>>> +        * Since the display/modeset side of DRM can only be owned by
>>> exactly
>>> +        * one &struct drm_file (see &drm_file.is_master and
>>> &drm_device.master)
>>> +        * there should never be a need to tear down any modeset related
>>> +        * resources in this callback. Doing so would be a driver design
>>> bug.
>>> +        *
>>> +        * FIXME: It is not really clear why there's both @preclose and
>>> +        * @postclose. Without a really good reason, use @postclose only.
>>> +        */
>>> +       void (*preclose) (struct drm_device *, struct drm_file
>>> *file_priv);
>>> +
>>>          /**
>>>           * @postclose:
>>>           *
>>> @@ -118,6 +135,9 @@ struct drm_driver {
>>>           * one &struct drm_file (see &drm_file.is_master and
>>> &drm_device.master)
>>>           * there should never be a need to tear down any modeset related
>>>           * resources in this callback. Doing so would be a driver design
>>> bug.
>>> +        *
>>> +        * FIXME: It is not really clear why there's both @preclose and
>>> +        * @postclose. Without a really good reason, use @postclose only.
>>>           */
>>>          void (*postclose) (struct drm_device *, struct drm_file *);
>>>    @@ -134,7 +154,7 @@ struct drm_driver {
>>>           * state changes, e.g. in conjunction with the
>>> :ref:`vga_switcheroo`
>>>           * infrastructure.
>>>           *
>>> -        * This is called after @postclose hook has been called.
>>> +        * This is called after @preclose and @postclose have been called.
>>>           *
>>>           * NOTE:
>>>           *
>>> @@ -601,7 +621,6 @@ struct drm_driver {
>>>          /* List of devices hanging off this driver with stealth attach. */
>>>          struct list_head legacy_dev_list;
>>>          int (*firstopen) (struct drm_device *);
>>> -       void (*preclose) (struct drm_device *, struct drm_file
>>> *file_priv);
>>>          int (*dma_ioctl) (struct drm_device *dev, void *data, struct
>>> drm_file *file_priv);
>>>          int (*dma_quiescent) (struct drm_device *);
>>>          int (*context_dtor) (struct drm_device *dev, int context);
>>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v11 1/2] cpufreq: Add Kryo CPU scaling driver
From: Sudeep Holla @ 2018-05-23 13:25 UTC (permalink / raw)
  To: Ilia Lin, vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm,
	devicetree, linux-kernel
  Cc: Sudeep Holla
In-Reply-To: <1527079139-3558-2-git-send-email-ilialin@codeaurora.org>



On 23/05/18 13:38, Ilia Lin wrote:
> In Certain QCOM SoCs like apq8096 and msm8996 that have KRYO processors,
> the CPU frequency subset and voltage value of each OPP varies
> based on the silicon variant in use. Qualcomm Process Voltage Scaling Tables
> defines the voltage and frequency value based on the msm-id in SMEM
> and speedbin blown in the efuse combination.
> The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> to provide the OPP framework with required information.
> This is used to determine the voltage and frequency value for each OPP of
> operating-points-v2 table when it is parsed by the OPP framework.
> 
> Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> ---
>  drivers/cpufreq/Kconfig.arm          |  10 ++
>  drivers/cpufreq/Makefile             |   1 +
>  drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
>  drivers/cpufreq/qcom-cpufreq-kryo.c  | 181 +++++++++++++++++++++++++++++++++++
>  4 files changed, 195 insertions(+)
>  create mode 100644 drivers/cpufreq/qcom-cpufreq-kryo.c
> 
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index de55c7d..0bfd40e 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -124,6 +124,16 @@ config ARM_OMAP2PLUS_CPUFREQ
>  	depends on ARCH_OMAP2PLUS
>  	default ARCH_OMAP2PLUS
>  
> +config ARM_QCOM_CPUFREQ_KRYO
> +	bool "Qualcomm Kryo based CPUFreq"
> +	depends on QCOM_QFPROM
> +	depends on QCOM_SMEM
> +	select PM_OPP
> +	help
> +	  This adds the CPUFreq driver for Qualcomm Kryo SoC based boards.
> +
> +	  If in doubt, say N.
> +

Sorry but just noticed now, any reason why this can't be module. I can't
imagine any.

[..]

> +static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
> +{
> +	struct opp_table *opp_tables[NR_CPUS] = {0};
> +	struct platform_device *cpufreq_dt_pdev;
> +	enum _msm8996_version msm8996_version;
> +	struct nvmem_cell *speedbin_nvmem;
> +	struct device_node *np;
> +	struct device *cpu_dev;

[..]

> +
> +	cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> +	if (!IS_ERR(cpufreq_dt_pdev))
> +		return 0;
> +
> +	ret = PTR_ERR(cpufreq_dt_pdev);
> +	dev_err(cpu_dev, "Failed to register platform device\n");
> +
> +free_opp:
> +	for_each_possible_cpu(cpu) {
> +		if (IS_ERR_OR_NULL(opp_tables[cpu]))
> +			break;
> +		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
> +	}
> +
> +	return ret;
> +}
> +
> +static int __init qcom_cpufreq_kryo_init(void)
> +{
> +	/*
> +	 * Since the driver depends on smem and nvmem drivers, which may
> +	 * return EPROBE_DEFER, all the real activity is done in the probe,
> +	 * which may be defered as well. The init here is only registering
> +	 * a platform device.
> +	 */
> +	platform_device_register_simple("qcom-cpufreq-kryo", -1, NULL, 0);
> +	return 0;
> +}
> +module_init(qcom_cpufreq_kryo_init);

Do you need this at all ? See below on how to eliminate the need for this.

> +
> +static struct platform_driver qcom_cpufreq_kryo_driver = {
> +	.probe = qcom_cpufreq_kryo_probe,
> +	.driver = {
> +		.name = "qcom-cpufreq-kryo",
> +	},
> +};
> +builtin_platform_driver(qcom_cpufreq_kryo_driver);

Use builtin_platform_driver_probe and remove qcom_cpufreq_kryo_init
or use module_platform_driver_probe if it can be module.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH RFC 00/24] Lima DRM driver
From: Qiang Yu @ 2018-05-23 13:24 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
	Neil Armstrong, Andrei Paulau, dri-devel, Vasily Khoruzhick,
	Erico Nunes
In-Reply-To: <20180523090223.GR3438@phenom.ffwll.local>

On Wed, May 23, 2018 at 5:02 PM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, May 18, 2018 at 05:27:51PM +0800, Qiang Yu wrote:
>> Kernel DRM driver for ARM Mali 400/450 GPUs.
>>
>> This implementation mainly take amdgpu DRM driver as reference.
>>
>> - Mali 4xx GPUs have two kinds of processors GP and PP. GP is for
>>   OpenGL vertex shader processing and PP is for fragment shader
>>   processing. Each processor has its own MMU so prcessors work in
>>   virtual address space.
>> - There's only one GP but multiple PP (max 4 for mali 400 and 8
>>   for mali 450) in the same mali 4xx GPU. All PPs are grouped
>>   togather to handle a single fragment shader task divided by
>>   FB output tiled pixels. Mali 400 user space driver is
>>   responsible for assign target tiled pixels to each PP, but mali
>>   450 has a HW module called DLBU to dynamically balance each
>>   PP's load.
>> - User space driver allocate buffer object and map into GPU
>>   virtual address space, upload command stream and draw data with
>>   CPU mmap of the buffer object, then submit task to GP/PP with
>>   a register frame indicating where is the command stream and misc
>>   settings.
>> - There's no command stream validation/relocation due to each user
>>   process has its own GPU virtual address space. GP/PP's MMU switch
>>   virtual address space before running two tasks from different
>>   user process. Error or evil user space code just get MMU fault
>>   or GP/PP error IRQ, then the HW/SW will be recovered.
>> - Use TTM as MM. TTM_PL_TT type memory is used as the content of
>>   lima buffer object which is allocated from TTM page pool. all
>>   lima buffer object gets pinned with TTM_PL_FLAG_NO_EVICT when
>>   allocation, so there's no buffer eviction and swap for now. We
>>   need reverse engineering to see if and how GP/PP support MMU
>>   fault recovery (continue execution). Otherwise we have to
>>   pin/unpin each envolved buffer when task creation/deletion.
>
> Curios question, but why? The one thing that ttm does help you with is
> keeping track of buffer moves from/to discrete memory. You get that
> benefit at the cost of a nice midlayer which tends to get in the way. If
> all you do is map buffers into pagetables, then rolling your own (like
> e.g. etnaviv does) is I think much better: All the other ttm functionality
> (reservatsions, drm_mm allocation management, fences) has all been
> extracted and is available to any driver without ttm.

Yeah, I can spend more time to write one without that much redundant
functionality of TTM, but as there's one that can be used directly, I give
up. I also see virtio GPU use this way.

If I'm going to write a new one, I also want the ttm_page_alloc.c page
pool. But my interface won't be that generic as TTM.

Regards,
Qiang

> -Daniel
>
>> - Use drm_sched for GPU task schedule. Each OpenGL context should
>>   have a lima context object in the kernel to distinguish tasks
>>   from different user. drm_sched gets task from each lima context
>>   in a fair way.
>>
>> Not implemented:
>> - Dump buffer support
>> - Power management
>> - Performance counter
>>
>> This patch serial just pack a pair of .c/.h files in each patch.
>> For whole history of this driver's development, see:
>> https://github.com/yuq/linux-lima/commits/lima-4.17-rc4
>>
>> Mesa driver is still in development and not ready for daily usage,
>> but can run some simple tests like kmscube and glamrk2, see:
>> https://github.com/yuq/mesa-lima
>>
>> Andrei Paulau (1):
>>   arm64/dts: add switch-delay for meson mali
>>
>> Lima Project Developers (10):
>>   drm/lima: add mali 4xx GPU hardware regs
>>   drm/lima: add lima core driver
>>   drm/lima: add GPU device functions
>>   drm/lima: add PMU related functions
>>   drm/lima: add PP related functions
>>   drm/lima: add MMU related functions
>>   drm/lima: add GPU virtual memory space handing
>>   drm/lima: add GEM related functions
>>   drm/lima: add GEM Prime related functions
>>   drm/lima: add makefile and kconfig
>>
>> Qiang Yu (12):
>>   dt-bindings: add switch-delay property for mali-utgard
>>   arm64/dts: add switch-delay for meson mali
>>   Revert "drm: Nerf the preclose callback for modern drivers"
>>   drm/lima: add lima uapi header
>>   drm/lima: add L2 cache functions
>>   drm/lima: add GP related functions
>>   drm/lima: add BCAST related function
>>   drm/lima: add DLBU related functions
>>   drm/lima: add TTM subsystem functions
>>   drm/lima: add buffer object functions
>>   drm/lima: add GPU schedule using DRM_SCHED
>>   drm/lima: add context related functions
>>
>> Simon Shields (1):
>>   ARM: dts: add gpu node to exynos4
>>
>>  .../bindings/gpu/arm,mali-utgard.txt          |   4 +
>>  arch/arm/boot/dts/exynos4.dtsi                |  33 ++
>>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi   |   1 +
>>  .../boot/dts/amlogic/meson-gxl-mali.dtsi      |   1 +
>>  drivers/gpu/drm/Kconfig                       |   2 +
>>  drivers/gpu/drm/Makefile                      |   1 +
>>  drivers/gpu/drm/drm_file.c                    |   8 +-
>>  drivers/gpu/drm/lima/Kconfig                  |   9 +
>>  drivers/gpu/drm/lima/Makefile                 |  19 +
>>  drivers/gpu/drm/lima/lima_bcast.c             |  65 +++
>>  drivers/gpu/drm/lima/lima_bcast.h             |  34 ++
>>  drivers/gpu/drm/lima/lima_ctx.c               | 143 +++++
>>  drivers/gpu/drm/lima/lima_ctx.h               |  51 ++
>>  drivers/gpu/drm/lima/lima_device.c            | 407 ++++++++++++++
>>  drivers/gpu/drm/lima/lima_device.h            | 136 +++++
>>  drivers/gpu/drm/lima/lima_dlbu.c              |  75 +++
>>  drivers/gpu/drm/lima/lima_dlbu.h              |  37 ++
>>  drivers/gpu/drm/lima/lima_drv.c               | 466 ++++++++++++++++
>>  drivers/gpu/drm/lima/lima_drv.h               |  77 +++
>>  drivers/gpu/drm/lima/lima_gem.c               | 459 ++++++++++++++++
>>  drivers/gpu/drm/lima/lima_gem.h               |  41 ++
>>  drivers/gpu/drm/lima/lima_gem_prime.c         |  66 +++
>>  drivers/gpu/drm/lima/lima_gem_prime.h         |  31 ++
>>  drivers/gpu/drm/lima/lima_gp.c                | 293 +++++++++++
>>  drivers/gpu/drm/lima/lima_gp.h                |  34 ++
>>  drivers/gpu/drm/lima/lima_l2_cache.c          |  98 ++++
>>  drivers/gpu/drm/lima/lima_l2_cache.h          |  32 ++
>>  drivers/gpu/drm/lima/lima_mmu.c               | 154 ++++++
>>  drivers/gpu/drm/lima/lima_mmu.h               |  34 ++
>>  drivers/gpu/drm/lima/lima_object.c            | 120 +++++
>>  drivers/gpu/drm/lima/lima_object.h            |  87 +++
>>  drivers/gpu/drm/lima/lima_pmu.c               |  85 +++
>>  drivers/gpu/drm/lima/lima_pmu.h               |  30 ++
>>  drivers/gpu/drm/lima/lima_pp.c                | 418 +++++++++++++++
>>  drivers/gpu/drm/lima/lima_pp.h                |  37 ++
>>  drivers/gpu/drm/lima/lima_regs.h              | 304 +++++++++++
>>  drivers/gpu/drm/lima/lima_sched.c             | 497 ++++++++++++++++++
>>  drivers/gpu/drm/lima/lima_sched.h             | 126 +++++
>>  drivers/gpu/drm/lima/lima_ttm.c               | 409 ++++++++++++++
>>  drivers/gpu/drm/lima/lima_ttm.h               |  44 ++
>>  drivers/gpu/drm/lima/lima_vm.c                | 312 +++++++++++
>>  drivers/gpu/drm/lima/lima_vm.h                |  73 +++
>>  include/drm/drm_drv.h                         |  23 +-
>>  include/uapi/drm/lima_drm.h                   | 195 +++++++
>>  44 files changed, 5565 insertions(+), 6 deletions(-)
>>  create mode 100644 drivers/gpu/drm/lima/Kconfig
>>  create mode 100644 drivers/gpu/drm/lima/Makefile
>>  create mode 100644 drivers/gpu/drm/lima/lima_bcast.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_bcast.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_ctx.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_ctx.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_device.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_device.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_drv.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_drv.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_gem.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_gem.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_gp.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_gp.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_mmu.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_object.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_object.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_pmu.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_pmu.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_pp.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_pp.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_regs.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_sched.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_sched.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_ttm.h
>>  create mode 100644 drivers/gpu/drm/lima/lima_vm.c
>>  create mode 100644 drivers/gpu/drm/lima/lima_vm.h
>>  create mode 100644 include/uapi/drm/lima_drm.h
>>
>> --
>> 2.17.0
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH RFC 05/24] Revert "drm: Nerf the preclose callback for modern drivers"
From: Qiang Yu @ 2018-05-23 13:13 UTC (permalink / raw)
  To: christian.koenig
  Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
	Neil Armstrong, Andrei Paulau, dri-devel, Vasily Khoruzhick,
	Erico Nunes
In-Reply-To: <9b48f845-9854-1029-ed21-df7b3590935b@gmail.com>

On Wed, May 23, 2018 at 5:35 PM, Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
> Well NAK, that brings back a callback we worked quite hard on getting rid
> of.
>
> It looks like the problem isn't that you need the preclose callback, but you
> rather seem to misunderstood how TTM works.
>
> All you need to do is to cleanup your command submission path so that the
> caller of lima_sched_context_queue_task() adds the resulting scheduler fence
> to TTMs buffer objects.

You mean adding the finished dma fence to the buffer's reservation object then
waiting it before unmap the buffer from GPU VM in the drm_release()'s buffer
close callback?

Adding fence is done already, and I did wait it before unmap. But then
I see when
the buffer is shared between processes, the "perfect wait" is just
wait the fence
from this process's task, so it's better to also distinguish fences.
If so, I just think
why we don't just wait tasks from this process in the preclose before unmap/free
buffer in the drm_release()?

Regards,
Qiang

>
>
> Am 18.05.2018 um 11:27 schrieb Qiang Yu:
>>
>> This reverts commit 45c3d213a400c952ab7119f394c5293bb6877e6b.
>>
>> lima driver need preclose to wait all task in the context
>> created within closing file to finish before free all the
>> buffer object. Otherwise pending tesk may fail and get
>> noisy MMU fault message.
>>
>> Move this wait to each buffer object free function can
>> achieve the same result but some buffer object is shared
>> with other file context, but we only want to wait the
>> closing file context's tasks. So the implementation is
>> not that straight forword compared to the preclose one.
>>
>> Signed-off-by: Qiang Yu <yuq825@gmail.com>
>> ---
>>   drivers/gpu/drm/drm_file.c |  8 ++++----
>>   include/drm/drm_drv.h      | 23 +++++++++++++++++++++--
>>   2 files changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
>> index e394799979a6..0a43107396b9 100644
>> --- a/drivers/gpu/drm/drm_file.c
>> +++ b/drivers/gpu/drm/drm_file.c
>> @@ -361,8 +361,9 @@ void drm_lastclose(struct drm_device * dev)
>>    *
>>    * This function must be used by drivers as their
>> &file_operations.release
>>    * method. It frees any resources associated with the open file, and
>> calls the
>> - * &drm_driver.postclose driver callback. If this is the last open file
>> for the
>> - * DRM device also proceeds to call the &drm_driver.lastclose driver
>> callback.
>> + * &drm_driver.preclose and &drm_driver.lastclose driver callbacks. If
>> this is
>> + * the last open file for the DRM device also proceeds to call the
>> + * &drm_driver.lastclose driver callback.
>>    *
>>    * RETURNS:
>>    *
>> @@ -382,8 +383,7 @@ int drm_release(struct inode *inode, struct file
>> *filp)
>>         list_del(&file_priv->lhead);
>>         mutex_unlock(&dev->filelist_mutex);
>>   -     if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
>> -           dev->driver->preclose)
>> +       if (dev->driver->preclose)
>>                 dev->driver->preclose(dev, file_priv);
>>         /* ========================================================
>> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
>> index d23dcdd1bd95..8d6080f97ed4 100644
>> --- a/include/drm/drm_drv.h
>> +++ b/include/drm/drm_drv.h
>> @@ -107,6 +107,23 @@ struct drm_driver {
>>          */
>>         int (*open) (struct drm_device *, struct drm_file *);
>>   +     /**
>> +        * @preclose:
>> +        *
>> +        * One of the driver callbacks when a new &struct drm_file is
>> closed.
>> +        * Useful for tearing down driver-private data structures
>> allocated in
>> +        * @open like buffer allocators, execution contexts or similar
>> things.
>> +        *
>> +        * Since the display/modeset side of DRM can only be owned by
>> exactly
>> +        * one &struct drm_file (see &drm_file.is_master and
>> &drm_device.master)
>> +        * there should never be a need to tear down any modeset related
>> +        * resources in this callback. Doing so would be a driver design
>> bug.
>> +        *
>> +        * FIXME: It is not really clear why there's both @preclose and
>> +        * @postclose. Without a really good reason, use @postclose only.
>> +        */
>> +       void (*preclose) (struct drm_device *, struct drm_file
>> *file_priv);
>> +
>>         /**
>>          * @postclose:
>>          *
>> @@ -118,6 +135,9 @@ struct drm_driver {
>>          * one &struct drm_file (see &drm_file.is_master and
>> &drm_device.master)
>>          * there should never be a need to tear down any modeset related
>>          * resources in this callback. Doing so would be a driver design
>> bug.
>> +        *
>> +        * FIXME: It is not really clear why there's both @preclose and
>> +        * @postclose. Without a really good reason, use @postclose only.
>>          */
>>         void (*postclose) (struct drm_device *, struct drm_file *);
>>   @@ -134,7 +154,7 @@ struct drm_driver {
>>          * state changes, e.g. in conjunction with the
>> :ref:`vga_switcheroo`
>>          * infrastructure.
>>          *
>> -        * This is called after @postclose hook has been called.
>> +        * This is called after @preclose and @postclose have been called.
>>          *
>>          * NOTE:
>>          *
>> @@ -601,7 +621,6 @@ struct drm_driver {
>>         /* List of devices hanging off this driver with stealth attach. */
>>         struct list_head legacy_dev_list;
>>         int (*firstopen) (struct drm_device *);
>> -       void (*preclose) (struct drm_device *, struct drm_file
>> *file_priv);
>>         int (*dma_ioctl) (struct drm_device *dev, void *data, struct
>> drm_file *file_priv);
>>         int (*dma_quiescent) (struct drm_device *);
>>         int (*context_dtor) (struct drm_device *dev, int context);
>
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* [PATCH v11 2/2] dt: qcom: Add qcom-cpufreq-kryo driver configuration
From: Ilia Lin @ 2018-05-23 13:11 UTC (permalink / raw)
  To: andy.gross, david.brown, robh, mark.rutland, catalin.marinas,
	will.deacon
  Cc: linux-arm-msm, linux-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <1527081091-13389-1-git-send-email-ilialin@codeaurora.org>

1. Add NVMEM node for the speedbin
2. Add definitions for all possible MSM8996 CPU OPPs.
The qcom-cpufreq-kryo driver will select the appropriate subset.

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 arch/arm64/boot/dts/qcom/apq8096-db820c.dts |   2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi       | 281 ++++++++++++++++++++++++++--
 2 files changed, 270 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
index 230e9c8..da23bda 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
@@ -17,5 +17,5 @@
 
 / {
 	model = "Qualcomm Technologies, Inc. DB820c";
-	compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc";
+	compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc", "qcom,apq8096";
 };
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index e6cf290..d96a112 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -1,13 +1,6 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -169,177 +162,436 @@
 	};
 
 	cluster0_opp: opp_table0 {
-		compatible = "operating-points-v2";
+		compatible = "operating-points-v2-kryo-cpu",
+					"operating-points-v2";
+		nvmem-cells = <&speedbin_efuse>;
 		opp-shared;
 
 		opp-307200000 {
 			opp-hz = /bits/ 64 <307200000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-422400000 {
 			opp-hz = /bits/ 64 <422400000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-480000000 {
 			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-556800000 {
 			opp-hz = /bits/ 64 <556800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-652800000 {
 			opp-hz = /bits/ 64 <652800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-729600000 {
 			opp-hz = /bits/ 64 <729600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-768000000 {
+			opp-hz = /bits/ 64 <768000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-844800000 {
 			opp-hz = /bits/ 64 <844800000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-960000000 {
 			opp-hz = /bits/ 64 <960000000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1036800000 {
 			opp-hz = /bits/ 64 <1036800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1113600000 {
 			opp-hz = /bits/ 64 <1113600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1190400000 {
 			opp-hz = /bits/ 64 <1190400000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1228800000 {
 			opp-hz = /bits/ 64 <1228800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1324800000 {
 			opp-hz = /bits/ 64 <1324800000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-supported-hw = <0x72>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1401600000 {
 			opp-hz = /bits/ 64 <1401600000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1478400000 {
 			opp-hz = /bits/ 64 <1478400000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-supported-hw = <0x4>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1593600000 {
 			opp-hz = /bits/ 64 <1593600000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			opp-supported-hw = <0x20>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2188800000 {
+			opp-hz = /bits/ 64 <2188800000>;
+			opp-supported-hw = <0x10>;
 			clock-latency-ns = <200000>;
 		};
 	};
 
 	cluster1_opp: opp_table1 {
-		compatible = "operating-points-v2";
+		compatible = "operating-points-v2-kryo-cpu";
+		nvmem-cells = <&speedbin_efuse>;
 		opp-shared;
 
 		opp-307200000 {
 			opp-hz = /bits/ 64 <307200000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-403200000 {
 			opp-hz = /bits/ 64 <403200000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-480000000 {
 			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-556800000 {
 			opp-hz = /bits/ 64 <556800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-652800000 {
 			opp-hz = /bits/ 64 <652800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-729600000 {
 			opp-hz = /bits/ 64 <729600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-748800000 {
+			opp-hz = /bits/ 64 <748800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-806400000 {
 			opp-hz = /bits/ 64 <806400000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-825600000 {
+			opp-hz = /bits/ 64 <825600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-883200000 {
 			opp-hz = /bits/ 64 <883200000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-940800000 {
 			opp-hz = /bits/ 64 <940800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1036800000 {
 			opp-hz = /bits/ 64 <1036800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1113600000 {
 			opp-hz = /bits/ 64 <1113600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1190400000 {
 			opp-hz = /bits/ 64 <1190400000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1248000000 {
 			opp-hz = /bits/ 64 <1248000000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1324800000 {
 			opp-hz = /bits/ 64 <1324800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1401600000 {
 			opp-hz = /bits/ 64 <1401600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1478400000 {
 			opp-hz = /bits/ 64 <1478400000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1555200000 {
 			opp-hz = /bits/ 64 <1555200000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1632000000 {
 			opp-hz = /bits/ 64 <1632000000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1670400000 {
+			opp-hz = /bits/ 64 <1670400000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1708800000 {
 			opp-hz = /bits/ 64 <1708800000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1747200000 {
+			opp-hz = /bits/ 64 <1747200000>;
+			opp-supported-hw = <0x70>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1785600000 {
 			opp-hz = /bits/ 64 <1785600000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1804800000 {
+			opp-hz = /bits/ 64 <1804800000>;
+			opp-supported-hw = <0x6>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1824000000 {
 			opp-hz = /bits/ 64 <1824000000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1900800000 {
+			opp-hz = /bits/ 64 <1900800000>;
+			opp-supported-hw = <0x74>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1920000000 {
 			opp-hz = /bits/ 64 <1920000000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1977600000 {
+			opp-hz = /bits/ 64 <1977600000>;
+			opp-supported-hw = <0x30>;
 			clock-latency-ns = <200000>;
 		};
 		opp-1996800000 {
 			opp-hz = /bits/ 64 <1996800000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2054400000 {
+			opp-hz = /bits/ 64 <2054400000>;
+			opp-supported-hw = <0x30>;
 			clock-latency-ns = <200000>;
 		};
 		opp-2073600000 {
 			opp-hz = /bits/ 64 <2073600000>;
+			opp-supported-hw = <0x1>;
 			clock-latency-ns = <200000>;
 		};
 		opp-2150400000 {
 			opp-hz = /bits/ 64 <2150400000>;
+			opp-supported-hw = <0x31>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2246400000 {
+			opp-hz = /bits/ 64 <2246400000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2342400000 {
+			opp-hz = /bits/ 64 <2342400000>;
+			opp-supported-hw = <0x10>;
 			clock-latency-ns = <200000>;
 		};
 	};
@@ -917,6 +1169,11 @@
 				reg = <0x24f 0x1>;
 				bits = <1 4>;
 			};
+
+			speedbin_efuse: speedbin@133 {
+				reg = <0x133 0x1>;
+				bits = <5 3>;
+			};
 		};
 
 		phy@34000 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 1/2] dt: qcom: Add opp and thermal to the msm8996
From: Ilia Lin @ 2018-05-23 13:11 UTC (permalink / raw)
  To: andy.gross, david.brown, robh, mark.rutland, catalin.marinas,
	will.deacon
  Cc: linux-arm-msm, linux-soc, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <1527081091-13389-1-git-send-email-ilialin@codeaurora.org>

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 269 ++++++++++++++++++++++++++++++++--
 1 file changed, 260 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 37b7152c..e6cf290 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/qcom,gcc-msm8996.h>
 #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	model = "Qualcomm Technologies, Inc. MSM8996";
@@ -97,6 +98,9 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 			next-level-cache = <&L2_0>;
 			L2_0: l2-cache {
 			      compatible = "cache";
@@ -109,6 +113,9 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
 			next-level-cache = <&L2_0>;
 		};
 
@@ -117,6 +124,9 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x100>;
 			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
 			next-level-cache = <&L2_1>;
 			L2_1: l2-cache {
 			      compatible = "cache";
@@ -129,6 +139,9 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x101>;
 			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
 			next-level-cache = <&L2_1>;
 		};
 
@@ -155,6 +168,182 @@
 		};
 	};
 
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-422400000 {
+			opp-hz = /bits/ 64 <422400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-844800000 {
+			opp-hz = /bits/ 64 <844800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-960000000 {
+			opp-hz = /bits/ 64 <960000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1228800000 {
+			opp-hz = /bits/ 64 <1228800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-403200000 {
+			opp-hz = /bits/ 64 <403200000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-806400000 {
+			opp-hz = /bits/ 64 <806400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-883200000 {
+			opp-hz = /bits/ 64 <883200000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-940800000 {
+			opp-hz = /bits/ 64 <940800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1248000000 {
+			opp-hz = /bits/ 64 <1248000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1555200000 {
+			opp-hz = /bits/ 64 <1555200000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1785600000 {
+			opp-hz = /bits/ 64 <1785600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1824000000 {
+			opp-hz = /bits/ 64 <1824000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1920000000 {
+			opp-hz = /bits/ 64 <1920000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2073600000 {
+			opp-hz = /bits/ 64 <2073600000>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2150400000 {
+			opp-hz = /bits/ 64 <2150400000>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
 	thermal-zones {
 		cpu-thermal0 {
 			polling-delay-passive = <250>;
@@ -163,18 +352,34 @@
 			thermal-sensors = <&tsens0 3>;
 
 			trips {
-				cpu_alert0: trip0 {
+				cpu_alert0: cpu_alert0 {
 					temperature = <75000>;
 					hysteresis = <2000>;
+					type = "active";
+				};
+				cpu_warn0: cpu_warn0 {
+					temperature = <90000>;
+					hysteresis = <2000>;
 					type = "passive";
 				};
 
-				cpu_crit0: trip1 {
+				cpu_crit0: cpu_crit0 {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device = <&CPU0 THERMAL_NO_LIMIT 7>;
+				};
+				map1 {
+					trip = <&cpu_warn0>;
+					cooling-device = <&CPU0 8 THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu-thermal1 {
@@ -184,18 +389,34 @@
 			thermal-sensors = <&tsens0 5>;
 
 			trips {
-				cpu_alert1: trip0 {
+				cpu_alert1: cpu_alert1 {
 					temperature = <75000>;
 					hysteresis = <2000>;
+					type = "active";
+				};
+				cpu_warn1: cpu_warn1 {
+					temperature = <90000>;
+					hysteresis = <2000>;
 					type = "passive";
 				};
 
-				cpu_crit1: trip1 {
+				cpu_crit1: cpu_crit1 {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert1>;
+					cooling-device = <&CPU0 THERMAL_NO_LIMIT 7>;
+				};
+				map1 {
+					trip = <&cpu_warn1>;
+					cooling-device = <&CPU0 8 THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu-thermal2 {
@@ -205,18 +426,33 @@
 			thermal-sensors = <&tsens0 8>;
 
 			trips {
-				cpu_alert2: trip0 {
+				cpu_alert2: cpu_alert2 {
 					temperature = <75000>;
 					hysteresis = <2000>;
+					type = "active";
+				};
+				cpu_warn2: cpu_warn2 {
+					temperature = <90000>;
+					hysteresis = <2000>;
 					type = "passive";
 				};
 
-				cpu_crit2: trip1 {
+				cpu_crit2: cpu_crit2 {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert2>;
+					cooling-device = <&CPU2 THERMAL_NO_LIMIT 7>;
+				};
+				map1 {
+					trip = <&cpu_warn2>;
+					cooling-device = <&CPU2 8 THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu-thermal3 {
@@ -226,9 +462,14 @@
 			thermal-sensors = <&tsens0 10>;
 
 			trips {
-				cpu_alert3: trip0 {
+				cpu_alert3: cpu_alert3 {
 					temperature = <75000>;
 					hysteresis = <2000>;
+					type = "active";
+				};
+				cpu_warn3: cpu_warn3 {
+					temperature = <90000>;
+					hysteresis = <2000>;
 					type = "passive";
 				};
 
@@ -238,6 +479,16 @@
 					type = "critical";
 				};
 			};
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert3>;
+					cooling-device = <&CPU2 THERMAL_NO_LIMIT 7>;
+				};
+				map1 {
+					trip = <&cpu_warn3>;
+					cooling-device = <&CPU2 8 THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 	};
 
@@ -414,7 +665,7 @@
 		};
 
 		kryocc: clock-controller@6400000 {
-			compatible = "qcom,apcc-msm8996";
+			compatible = "qcom,msm8996-apcc";
 			reg = <0x6400000 0x90000>;
 			#clock-cells = <1>;
 		};
@@ -1001,7 +1252,7 @@
 
 				pinctrl-names = "default", "sleep";
 				pinctrl-0 = <&pcie2_clkreq_default &pcie2_perst_default &pcie2_wake_default>;
-				pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep >;
+				pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep>;
 
 				vdda-supply = <&pm8994_l28>;
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 0/2] CPU scaling support for msm8996 DT
From: Ilia Lin @ 2018-05-23 13:11 UTC (permalink / raw)
  To: andy.gross, david.brown, robh, mark.rutland, catalin.marinas,
	will.deacon
  Cc: linux-arm-msm, linux-soc, devicetree, linux-arm-kernel,
	linux-kernel

[v11]
 * Split the series into domains

The series adds OPP tables, thermal and CPU definitions in order to support
the CPU frequency scaling on msm8996 CPUs.

Ilia Lin (2):
  dt: qcom: Add opp and thermal to the msm8996
  dt: qcom: Add qcom-cpufreq-kryo driver configuration

 arch/arm64/boot/dts/qcom/apq8096-db820c.dts |   2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi       | 546 +++++++++++++++++++++++++++-
 2 files changed, 528 insertions(+), 20 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH v11 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-23 12:53 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: <1527079981-11179-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

* [PATCH v11 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz
From: Ilia Lin @ 2018-05-23 12:53 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: <1527079981-11179-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 v11 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL
From: Ilia Lin @ 2018-05-23 12:52 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: <1527079981-11179-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 v11 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
From: Ilia Lin @ 2018-05-23 12:52 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: <1527079981-11179-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 v11 4/8] clk: qcom: Add CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-23 12:52 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: <1527079981-11179-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         |   9 +
 drivers/clk/qcom/Makefile        |   1 +
 drivers/clk/qcom/clk-alpha-pll.h |   6 +
 drivers/clk/qcom/clk-cpu-8996.c  | 403 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 419 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..866ce1f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,15 @@ 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 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 v11 3/8] clk: Use devm_ in the register fixed factor clock
From: Ilia Lin @ 2018-05-23 12:52 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: <1527079981-11179-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 v11 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules
From: Ilia Lin @ 2018-05-23 12:52 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: <1527079981-11179-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 v11 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver
From: Ilia Lin @ 2018-05-23 12:52 UTC (permalink / raw)
  To: mturquette, sboyd, robh, mark.rutland, andy.gross, david.brown,
	will.deacon
  Cc: devicetree, linux-arm-msm, ilialin, linux-kernel, vireshk,
	linux-soc, linux-clk, linux-arm-kernel
In-Reply-To: <1527079981-11179-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 v11 0/8] CPU scaling support for msm8996
From: Ilia Lin @ 2018-05-23 12:52 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

[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                           |   9 +
 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, 642 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 v11 2/2] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Ilia Lin @ 2018-05-23 12:38 UTC (permalink / raw)
  To: vireshk, nm, sboyd, robh, mark.rutland, rjw, linux-pm, devicetree,
	linux-kernel
In-Reply-To: <1527079139-3558-1-git-send-email-ilialin@codeaurora.org>

The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
to provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each OPP of
operating-points-v2 table when it is parsed by the OPP framework.

This change adds documentation for the DT bindings.
The "operating-points-v2-kryo-cpu" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-supported-hw: A single 32 bit bitmap value,
  representing compatible HW:
			0:	MSM8996 V3, speedbin 0
			1:	MSM8996 V3, speedbin 1
			2:	MSM8996 V3, speedbin 2
			3:	unused
			4:	MSM8996 SG, speedbin 0
			5:	MSM8996 SG, speedbin 1
			6:	MSM8996 SG, speedbin 2
			7-31:	unused

Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 .../devicetree/bindings/opp/kryo-cpufreq.txt       | 680 +++++++++++++++++++++
 1 file changed, 680 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
new file mode 100644
index 0000000..c2127b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
@@ -0,0 +1,680 @@
+Qualcomm Technologies, Inc. KRYO CPUFreq and OPP bindings
+===================================
+
+In Certain Qualcomm Technologies, Inc. SoCs like apq8096 and msm8996
+that have KRYO processors, the CPU ferequencies subset and voltage value
+of each OPP varies based on the silicon variant in use.
+Qualcomm Technologies, Inc. Process Voltage Scaling Tables
+defines the voltage and frequency value based on the msm-id in SMEM
+and speedbin blown in the efuse combination.
+The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
+to provide the OPP framework with required information (existing HW bitmap).
+This is used to determine the voltage and frequency value for each OPP of
+operating-points-v2 table when it is parsed by the OPP framework.
+
+Required properties:
+--------------------
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+	- 'operating-points-v2-kryo-cpu' for apq8096 and msm8996.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+		efuse registers that has information about the
+		speedbin that is used to select the right frequency/voltage
+		value pair.
+		Please refer the for nvmem-cells
+		bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+		and also examples below.
+
+In every OPP node:
+- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW.
+		    Bitmap:
+			0:	MSM8996 V3, speedbin 0
+			1:	MSM8996 V3, speedbin 1
+			2:	MSM8996 V3, speedbin 2
+			3:	unused
+			4:	MSM8996 SG, speedbin 0
+			5:	MSM8996 SG, speedbin 1
+			6:	MSM8996 SG, speedbin 2
+			7-31:	unused
+
+Example 1:
+---------
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			};
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			clocks = <&kryocc 0>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster0_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU2: cpu@100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_1>;
+			L2_1: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			};
+		};
+
+		CPU3: cpu@101 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			clocks = <&kryocc 1>;
+			cpu-supply = <&pm8994_s11_saw>;
+			operating-points-v2 = <&cluster1_opp>;
+			#cooling-cells = <2>;
+			next-level-cache = <&L2_1>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+
+				core1 {
+					cpu = <&CPU1>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU2>;
+				};
+
+				core1 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+	};
+
+	cluster0_opp: opp_table0 {
+		compatible = "operating-points-v2-kryo-cpu";
+		nvmem-cells = <&speedbin_efuse>;
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-422400000 {
+			opp-hz = /bits/ 64 <422400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-768000000 {
+			opp-hz = /bits/ 64 <768000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-844800000 {
+			opp-hz = /bits/ 64 <844800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-960000000 {
+			opp-hz = /bits/ 64 <960000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1228800000 {
+			opp-hz = /bits/ 64 <1228800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x72>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x5>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x4>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x20>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2188800000 {
+			opp-hz = /bits/ 64 <2188800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
+	cluster1_opp: opp_table1 {
+		compatible = "operating-points-v2-kryo-cpu";
+		nvmem-cells = <&speedbin_efuse>;
+		opp-shared;
+
+		opp-307200000 {
+			opp-hz = /bits/ 64 <307200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x77>;
+			clock-latency-ns = <200000>;
+		};
+		opp-384000000 {
+			opp-hz = /bits/ 64 <384000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-403200000 {
+			opp-hz = /bits/ 64 <403200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-460800000 {
+			opp-hz = /bits/ 64 <460800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-537600000 {
+			opp-hz = /bits/ 64 <537600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-556800000 {
+			opp-hz = /bits/ 64 <556800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-614400000 {
+			opp-hz = /bits/ 64 <614400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-691200000 {
+			opp-hz = /bits/ 64 <691200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-729600000 {
+			opp-hz = /bits/ 64 <729600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-748800000 {
+			opp-hz = /bits/ 64 <748800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-806400000 {
+			opp-hz = /bits/ 64 <806400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-825600000 {
+			opp-hz = /bits/ 64 <825600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-883200000 {
+			opp-hz = /bits/ 64 <883200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-940800000 {
+			opp-hz = /bits/ 64 <940800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1036800000 {
+			opp-hz = /bits/ 64 <1036800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1248000000 {
+			opp-hz = /bits/ 64 <1248000000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			opp-microvolt = <905000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1401600000 {
+			opp-hz = /bits/ 64 <1401600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1440000000 {
+			opp-hz = /bits/ 64 <1440000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1478400000 {
+			opp-hz = /bits/ 64 <1478400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1555200000 {
+			opp-hz = /bits/ 64 <1555200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1593600000 {
+			opp-hz = /bits/ 64 <1593600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1670400000 {
+			opp-hz = /bits/ 64 <1670400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1747200000 {
+			opp-hz = /bits/ 64 <1747200000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x70>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1785600000 {
+			opp-hz = /bits/ 64 <1785600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x7>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1804800000 {
+			opp-hz = /bits/ 64 <1804800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x6>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1824000000 {
+			opp-hz = /bits/ 64 <1824000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x71>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1900800000 {
+			opp-hz = /bits/ 64 <1900800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x74>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1920000000 {
+			opp-hz = /bits/ 64 <1920000000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1977600000 {
+			opp-hz = /bits/ 64 <1977600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x30>;
+			clock-latency-ns = <200000>;
+		};
+		opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2054400000 {
+			opp-hz = /bits/ 64 <2054400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x30>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2073600000 {
+			opp-hz = /bits/ 64 <2073600000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x1>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2150400000 {
+			opp-hz = /bits/ 64 <2150400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x31>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2246400000 {
+			opp-hz = /bits/ 64 <2246400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+		opp-2342400000 {
+			opp-hz = /bits/ 64 <2342400000>;
+			opp-microvolt = <1140000 905000 1140000>;
+			opp-supported-hw = <0x10>;
+			clock-latency-ns = <200000>;
+		};
+	};
+
+....
+
+reserved-memory {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+....
+	smem_mem: smem-mem@86000000 {
+		reg = <0x0 0x86000000 0x0 0x200000>;
+		no-map;
+	};
+....
+};
+
+smem {
+	compatible = "qcom,smem";
+	memory-region = <&smem_mem>;
+	hwlocks = <&tcsr_mutex 3>;
+};
+
+soc {
+....
+	qfprom: qfprom@74000 {
+		compatible = "qcom,qfprom";
+		reg = <0x00074000 0x8ff>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		....
+		speedbin_efuse: speedbin@133 {
+			reg = <0x133 0x1>;
+			bits = <5 3>;
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related


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