1 /* 2 * Copyright (C) 2014 Linaro Ltd. 3 * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * PCC (Platform Communication Channel) is defined in the ACPI 5.0+ 16 * specification. It is a mailbox like mechanism to allow clients 17 * such as CPPC (Collaborative Processor Performance Control), RAS 18 * (Reliability, Availability and Serviceability) and MPST (Memory 19 * Node Power State Table) to talk to the platform (e.g. BMC) through 20 * shared memory regions as defined in the PCC table entries. The PCC 21 * specification supports a Doorbell mechanism for the PCC clients 22 * to notify the platform about new data. This Doorbell information 23 * is also specified in each PCC table entry. 24 * 25 * Typical high level flow of operation is: 26 * 27 * PCC Reads: 28 * * Client tries to acquire a channel lock. 29 * * After it is acquired it writes READ cmd in communication region cmd 30 * address. 31 * * Client issues mbox_send_message() which rings the PCC doorbell 32 * for its PCC channel. 33 * * If command completes, then client has control over channel and 34 * it can proceed with its reads. 35 * * Client releases lock. 36 * 37 * PCC Writes: 38 * * Client tries to acquire channel lock. 39 * * Client writes to its communication region after it acquires a 40 * channel lock. 41 * * Client writes WRITE cmd in communication region cmd address. 42 * * Client issues mbox_send_message() which rings the PCC doorbell 43 * for its PCC channel. 44 * * If command completes, then writes have succeded and it can release 45 * the channel lock. 46 * 47 * There is a Nominal latency defined for each channel which indicates 48 * how long to wait until a command completes. If command is not complete 49 * the client needs to retry or assume failure. 50 * 51 * For more details about PCC, please see the ACPI specification from 52 * http://www.uefi.org/ACPIv5.1 Section 14. 53 * 54 * This file implements PCC as a Mailbox controller and allows for PCC 55 * clients to be implemented as its Mailbox Client Channels. 56 */ 57 58 #include <linux/acpi.h> 59 #include <linux/delay.h> 60 #include <linux/io.h> 61 #include <linux/init.h> 62 #include <linux/list.h> 63 #include <linux/platform_device.h> 64 #include <linux/mailbox_controller.h> 65 #include <linux/mailbox_client.h> 66 67 #include "mailbox.h" 68 69 #define MAX_PCC_SUBSPACES 256 70 71 static struct mbox_chan *pcc_mbox_channels; 72 73 static struct mbox_controller pcc_mbox_ctrl = {}; 74 /** 75 * get_pcc_channel - Given a PCC subspace idx, get 76 * the respective mbox_channel. 77 * @id: PCC subspace index. 78 * 79 * Return: ERR_PTR(errno) if error, else pointer 80 * to mbox channel. 81 */ 82 static struct mbox_chan *get_pcc_channel(int id) 83 { 84 struct mbox_chan *pcc_chan; 85 86 if (id < 0 || id > pcc_mbox_ctrl.num_chans) 87 return ERR_PTR(-ENOENT); 88 89 pcc_chan = (struct mbox_chan *) 90 (unsigned long) pcc_mbox_channels + 91 (id * sizeof(*pcc_chan)); 92 93 return pcc_chan; 94 } 95 96 /** 97 * pcc_mbox_request_channel - PCC clients call this function to 98 * request a pointer to their PCC subspace, from which they 99 * can get the details of communicating with the remote. 100 * @cl: Pointer to Mailbox client, so we know where to bind the 101 * Channel. 102 * @subspace_id: The PCC Subspace index as parsed in the PCC client 103 * ACPI package. This is used to lookup the array of PCC 104 * subspaces as parsed by the PCC Mailbox controller. 105 * 106 * Return: Pointer to the Mailbox Channel if successful or 107 * ERR_PTR. 108 */ 109 struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, 110 int subspace_id) 111 { 112 struct device *dev = pcc_mbox_ctrl.dev; 113 struct mbox_chan *chan; 114 unsigned long flags; 115 116 /* 117 * Each PCC Subspace is a Mailbox Channel. 118 * The PCC Clients get their PCC Subspace ID 119 * from their own tables and pass it here. 120 * This returns a pointer to the PCC subspace 121 * for the Client to operate on. 122 */ 123 chan = get_pcc_channel(subspace_id); 124 125 if (!chan || chan->cl) { 126 dev_err(dev, "Channel not found for idx: %d\n", subspace_id); 127 return ERR_PTR(-EBUSY); 128 } 129 130 spin_lock_irqsave(&chan->lock, flags); 131 chan->msg_free = 0; 132 chan->msg_count = 0; 133 chan->active_req = NULL; 134 chan->cl = cl; 135 init_completion(&chan->tx_complete); 136 137 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) 138 chan->txdone_method |= TXDONE_BY_ACK; 139 140 spin_unlock_irqrestore(&chan->lock, flags); 141 142 return chan; 143 } 144 EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); 145 146 /** 147 * pcc_mbox_free_channel - Clients call this to free their Channel. 148 * 149 * @chan: Pointer to the mailbox channel as returned by 150 * pcc_mbox_request_channel() 151 */ 152 void pcc_mbox_free_channel(struct mbox_chan *chan) 153 { 154 unsigned long flags; 155 156 if (!chan || !chan->cl) 157 return; 158 159 spin_lock_irqsave(&chan->lock, flags); 160 chan->cl = NULL; 161 chan->active_req = NULL; 162 if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK)) 163 chan->txdone_method = TXDONE_BY_POLL; 164 165 spin_unlock_irqrestore(&chan->lock, flags); 166 } 167 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); 168 169 /** 170 * pcc_send_data - Called from Mailbox Controller code. Used 171 * here only to ring the channel doorbell. The PCC client 172 * specific read/write is done in the client driver in 173 * order to maintain atomicity over PCC channel once 174 * OS has control over it. See above for flow of operations. 175 * @chan: Pointer to Mailbox channel over which to send data. 176 * @data: Client specific data written over channel. Used here 177 * only for debug after PCC transaction completes. 178 * 179 * Return: Err if something failed else 0 for success. 180 */ 181 static int pcc_send_data(struct mbox_chan *chan, void *data) 182 { 183 struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv; 184 struct acpi_generic_address doorbell; 185 u64 doorbell_preserve; 186 u64 doorbell_val; 187 u64 doorbell_write; 188 189 doorbell = pcct_ss->doorbell_register; 190 doorbell_preserve = pcct_ss->preserve_mask; 191 doorbell_write = pcct_ss->write_mask; 192 193 /* Sync notification from OS to Platform. */ 194 acpi_read(&doorbell_val, &doorbell); 195 acpi_write((doorbell_val & doorbell_preserve) | doorbell_write, 196 &doorbell); 197 198 return 0; 199 } 200 201 static const struct mbox_chan_ops pcc_chan_ops = { 202 .send_data = pcc_send_data, 203 }; 204 205 /** 206 * parse_pcc_subspace - Parse the PCC table and verify PCC subspace 207 * entries. There should be one entry per PCC client. 208 * @header: Pointer to the ACPI subtable header under the PCCT. 209 * @end: End of subtable entry. 210 * 211 * Return: 0 for Success, else errno. 212 * 213 * This gets called for each entry in the PCC table. 214 */ 215 static int parse_pcc_subspace(struct acpi_subtable_header *header, 216 const unsigned long end) 217 { 218 struct acpi_pcct_hw_reduced *pcct_ss; 219 220 if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { 221 pcct_ss = (struct acpi_pcct_hw_reduced *) header; 222 223 if (pcct_ss->header.type != 224 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) { 225 pr_err("Incorrect PCC Subspace type detected\n"); 226 return -EINVAL; 227 } 228 } 229 230 return 0; 231 } 232 233 /** 234 * acpi_pcc_probe - Parse the ACPI tree for the PCCT. 235 * 236 * Return: 0 for Success, else errno. 237 */ 238 static int __init acpi_pcc_probe(void) 239 { 240 acpi_size pcct_tbl_header_size; 241 struct acpi_table_header *pcct_tbl; 242 struct acpi_subtable_header *pcct_entry; 243 int count, i; 244 acpi_status status = AE_OK; 245 246 /* Search for PCCT */ 247 status = acpi_get_table_with_size(ACPI_SIG_PCCT, 0, 248 &pcct_tbl, 249 &pcct_tbl_header_size); 250 251 if (ACPI_FAILURE(status) || !pcct_tbl) { 252 pr_warn("PCCT header not found.\n"); 253 return -ENODEV; 254 } 255 256 count = acpi_table_parse_entries(ACPI_SIG_PCCT, 257 sizeof(struct acpi_table_pcct), 258 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, 259 parse_pcc_subspace, MAX_PCC_SUBSPACES); 260 261 if (count <= 0) { 262 pr_err("Error parsing PCC subspaces from PCCT\n"); 263 return -EINVAL; 264 } 265 266 pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * 267 count, GFP_KERNEL); 268 269 if (!pcc_mbox_channels) { 270 pr_err("Could not allocate space for PCC mbox channels\n"); 271 return -ENOMEM; 272 } 273 274 /* Point to the first PCC subspace entry */ 275 pcct_entry = (struct acpi_subtable_header *) ( 276 (unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct)); 277 278 for (i = 0; i < count; i++) { 279 pcc_mbox_channels[i].con_priv = pcct_entry; 280 pcct_entry = (struct acpi_subtable_header *) 281 ((unsigned long) pcct_entry + pcct_entry->length); 282 } 283 284 pcc_mbox_ctrl.num_chans = count; 285 286 pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); 287 288 return 0; 289 } 290 291 /** 292 * pcc_mbox_probe - Called when we find a match for the 293 * PCCT platform device. This is purely used to represent 294 * the PCCT as a virtual device for registering with the 295 * generic Mailbox framework. 296 * 297 * @pdev: Pointer to platform device returned when a match 298 * is found. 299 * 300 * Return: 0 for Success, else errno. 301 */ 302 static int pcc_mbox_probe(struct platform_device *pdev) 303 { 304 int ret = 0; 305 306 pcc_mbox_ctrl.chans = pcc_mbox_channels; 307 pcc_mbox_ctrl.ops = &pcc_chan_ops; 308 pcc_mbox_ctrl.dev = &pdev->dev; 309 310 pr_info("Registering PCC driver as Mailbox controller\n"); 311 ret = mbox_controller_register(&pcc_mbox_ctrl); 312 313 if (ret) { 314 pr_err("Err registering PCC as Mailbox controller: %d\n", ret); 315 ret = -ENODEV; 316 } 317 318 return ret; 319 } 320 321 struct platform_driver pcc_mbox_driver = { 322 .probe = pcc_mbox_probe, 323 .driver = { 324 .name = "PCCT", 325 .owner = THIS_MODULE, 326 }, 327 }; 328 329 static int __init pcc_init(void) 330 { 331 int ret; 332 struct platform_device *pcc_pdev; 333 334 if (acpi_disabled) 335 return -ENODEV; 336 337 /* Check if PCC support is available. */ 338 ret = acpi_pcc_probe(); 339 340 if (ret) { 341 pr_debug("ACPI PCC probe failed.\n"); 342 return -ENODEV; 343 } 344 345 pcc_pdev = platform_create_bundle(&pcc_mbox_driver, 346 pcc_mbox_probe, NULL, 0, NULL, 0); 347 348 if (IS_ERR(pcc_pdev)) { 349 pr_debug("Err creating PCC platform bundle\n"); 350 return PTR_ERR(pcc_pdev); 351 } 352 353 return 0; 354 } 355 device_initcall(pcc_init); 356