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. See pcc_send_data() 24 * and pcc_tx_done() for basic mode of operation. 25 * 26 * For more details about PCC, please see the ACPI specification from 27 * http://www.uefi.org/ACPIv5.1 Section 14. 28 * 29 * This file implements PCC as a Mailbox controller and allows for PCC 30 * clients to be implemented as its Mailbox Client Channels. 31 */ 32 33 #include <linux/acpi.h> 34 #include <linux/delay.h> 35 #include <linux/io.h> 36 #include <linux/init.h> 37 #include <linux/list.h> 38 #include <linux/platform_device.h> 39 #include <linux/mailbox_controller.h> 40 #include <linux/mailbox_client.h> 41 42 #include "mailbox.h" 43 44 #define MAX_PCC_SUBSPACES 256 45 #define PCCS_SS_SIG_MAGIC 0x50434300 46 #define PCC_CMD_COMPLETE 0x1 47 48 static struct mbox_chan *pcc_mbox_channels; 49 50 static struct mbox_controller pcc_mbox_ctrl = {}; 51 /** 52 * get_pcc_channel - Given a PCC subspace idx, get 53 * the respective mbox_channel. 54 * @id: PCC subspace index. 55 * 56 * Return: ERR_PTR(errno) if error, else pointer 57 * to mbox channel. 58 */ 59 static struct mbox_chan *get_pcc_channel(int id) 60 { 61 struct mbox_chan *pcc_chan; 62 63 if (id < 0 || id > pcc_mbox_ctrl.num_chans) 64 return ERR_PTR(-ENOENT); 65 66 pcc_chan = (struct mbox_chan *) 67 (unsigned long) pcc_mbox_channels + 68 (id * sizeof(*pcc_chan)); 69 70 return pcc_chan; 71 } 72 73 /** 74 * get_subspace_id - Given a Mailbox channel, find out the 75 * PCC subspace id. 76 * @chan: Pointer to Mailbox Channel from which we want 77 * the index. 78 * Return: Errno if not found, else positive index number. 79 */ 80 static int get_subspace_id(struct mbox_chan *chan) 81 { 82 unsigned int id = chan - pcc_mbox_channels; 83 84 if (id < 0 || id > pcc_mbox_ctrl.num_chans) 85 return -ENOENT; 86 87 return id; 88 } 89 90 /** 91 * pcc_mbox_request_channel - PCC clients call this function to 92 * request a pointer to their PCC subspace, from which they 93 * can get the details of communicating with the remote. 94 * @cl: Pointer to Mailbox client, so we know where to bind the 95 * Channel. 96 * @subspace_id: The PCC Subspace index as parsed in the PCC client 97 * ACPI package. This is used to lookup the array of PCC 98 * subspaces as parsed by the PCC Mailbox controller. 99 * 100 * Return: Pointer to the Mailbox Channel if successful or 101 * ERR_PTR. 102 */ 103 struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, 104 int subspace_id) 105 { 106 struct device *dev = pcc_mbox_ctrl.dev; 107 struct mbox_chan *chan; 108 unsigned long flags; 109 110 /* 111 * Each PCC Subspace is a Mailbox Channel. 112 * The PCC Clients get their PCC Subspace ID 113 * from their own tables and pass it here. 114 * This returns a pointer to the PCC subspace 115 * for the Client to operate on. 116 */ 117 chan = get_pcc_channel(subspace_id); 118 119 if (!chan || chan->cl) { 120 dev_err(dev, "%s: PCC mailbox not free\n", __func__); 121 return ERR_PTR(-EBUSY); 122 } 123 124 spin_lock_irqsave(&chan->lock, flags); 125 chan->msg_free = 0; 126 chan->msg_count = 0; 127 chan->active_req = NULL; 128 chan->cl = cl; 129 init_completion(&chan->tx_complete); 130 131 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) 132 chan->txdone_method |= TXDONE_BY_ACK; 133 134 spin_unlock_irqrestore(&chan->lock, flags); 135 136 return chan; 137 } 138 EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); 139 140 /** 141 * pcc_mbox_free_channel - Clients call this to free their Channel. 142 * 143 * @chan: Pointer to the mailbox channel as returned by 144 * pcc_mbox_request_channel() 145 */ 146 void pcc_mbox_free_channel(struct mbox_chan *chan) 147 { 148 unsigned long flags; 149 150 if (!chan || !chan->cl) 151 return; 152 153 spin_lock_irqsave(&chan->lock, flags); 154 chan->cl = NULL; 155 chan->active_req = NULL; 156 if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK)) 157 chan->txdone_method = TXDONE_BY_POLL; 158 159 spin_unlock_irqrestore(&chan->lock, flags); 160 } 161 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); 162 163 /** 164 * pcc_tx_done - Callback from Mailbox controller code to 165 * check if PCC message transmission completed. 166 * @chan: Pointer to Mailbox channel on which previous 167 * transmission occurred. 168 * 169 * Return: TRUE if succeeded. 170 */ 171 static bool pcc_tx_done(struct mbox_chan *chan) 172 { 173 struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv; 174 struct acpi_pcct_shared_memory *generic_comm_base = 175 (struct acpi_pcct_shared_memory *) pcct_ss->base_address; 176 u16 cmd_delay = pcct_ss->latency; 177 unsigned int retries = 0; 178 179 /* Try a few times while waiting for platform to consume */ 180 while (!(readw_relaxed(&generic_comm_base->status) 181 & PCC_CMD_COMPLETE)) { 182 183 if (retries++ < 5) 184 udelay(cmd_delay); 185 else { 186 /* 187 * If the remote is dead, this will cause the Mbox 188 * controller to timeout after mbox client.tx_tout 189 * msecs. 190 */ 191 pr_err("PCC platform did not respond.\n"); 192 return false; 193 } 194 } 195 return true; 196 } 197 198 /** 199 * pcc_send_data - Called from Mailbox Controller code to finally 200 * transmit data over channel. 201 * @chan: Pointer to Mailbox channel over which to send data. 202 * @data: Actual data to be written over channel. 203 * 204 * Return: Err if something failed else 0 for success. 205 */ 206 static int pcc_send_data(struct mbox_chan *chan, void *data) 207 { 208 struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv; 209 struct acpi_pcct_shared_memory *generic_comm_base = 210 (struct acpi_pcct_shared_memory *) pcct_ss->base_address; 211 struct acpi_generic_address doorbell; 212 u64 doorbell_preserve; 213 u64 doorbell_val; 214 u64 doorbell_write; 215 u16 cmd = *(u16 *) data; 216 u16 ss_idx = -1; 217 218 ss_idx = get_subspace_id(chan); 219 220 if (ss_idx < 0) { 221 pr_err("Invalid Subspace ID from PCC client\n"); 222 return -EINVAL; 223 } 224 225 doorbell = pcct_ss->doorbell_register; 226 doorbell_preserve = pcct_ss->preserve_mask; 227 doorbell_write = pcct_ss->write_mask; 228 229 /* Write to the shared comm region. */ 230 writew(cmd, &generic_comm_base->command); 231 232 /* Write Subspace MAGIC value so platform can identify destination. */ 233 writel((PCCS_SS_SIG_MAGIC | ss_idx), &generic_comm_base->signature); 234 235 /* Flip CMD COMPLETE bit */ 236 writew(0, &generic_comm_base->status); 237 238 /* Sync notification from OSPM to Platform. */ 239 acpi_read(&doorbell_val, &doorbell); 240 acpi_write((doorbell_val & doorbell_preserve) | doorbell_write, 241 &doorbell); 242 243 return 0; 244 } 245 246 static struct mbox_chan_ops pcc_chan_ops = { 247 .send_data = pcc_send_data, 248 .last_tx_done = pcc_tx_done, 249 }; 250 251 /** 252 * parse_pcc_subspace - Parse the PCC table and verify PCC subspace 253 * entries. There should be one entry per PCC client. 254 * @header: Pointer to the ACPI subtable header under the PCCT. 255 * @end: End of subtable entry. 256 * 257 * Return: 0 for Success, else errno. 258 * 259 * This gets called for each entry in the PCC table. 260 */ 261 static int parse_pcc_subspace(struct acpi_subtable_header *header, 262 const unsigned long end) 263 { 264 struct acpi_pcct_hw_reduced *pcct_ss; 265 266 if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { 267 pcct_ss = (struct acpi_pcct_hw_reduced *) header; 268 269 if (pcct_ss->header.type != 270 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) { 271 pr_err("Incorrect PCC Subspace type detected\n"); 272 return -EINVAL; 273 } 274 } 275 276 return 0; 277 } 278 279 /** 280 * acpi_pcc_probe - Parse the ACPI tree for the PCCT. 281 * 282 * Return: 0 for Success, else errno. 283 */ 284 static int __init acpi_pcc_probe(void) 285 { 286 acpi_size pcct_tbl_header_size; 287 struct acpi_table_header *pcct_tbl; 288 struct acpi_subtable_header *pcct_entry; 289 int count, i; 290 acpi_status status = AE_OK; 291 292 /* Search for PCCT */ 293 status = acpi_get_table_with_size(ACPI_SIG_PCCT, 0, 294 &pcct_tbl, 295 &pcct_tbl_header_size); 296 297 if (ACPI_FAILURE(status) || !pcct_tbl) { 298 pr_warn("PCCT header not found.\n"); 299 return -ENODEV; 300 } 301 302 count = acpi_table_parse_entries(ACPI_SIG_PCCT, 303 sizeof(struct acpi_table_pcct), 304 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, 305 parse_pcc_subspace, MAX_PCC_SUBSPACES); 306 307 if (count <= 0) { 308 pr_err("Error parsing PCC subspaces from PCCT\n"); 309 return -EINVAL; 310 } 311 312 pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * 313 count, GFP_KERNEL); 314 315 if (!pcc_mbox_channels) { 316 pr_err("Could not allocate space for PCC mbox channels\n"); 317 return -ENOMEM; 318 } 319 320 /* Point to the first PCC subspace entry */ 321 pcct_entry = (struct acpi_subtable_header *) ( 322 (unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct)); 323 324 for (i = 0; i < count; i++) { 325 pcc_mbox_channels[i].con_priv = pcct_entry; 326 pcct_entry = (struct acpi_subtable_header *) 327 ((unsigned long) pcct_entry + pcct_entry->length); 328 } 329 330 pcc_mbox_ctrl.num_chans = count; 331 332 pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); 333 334 return 0; 335 } 336 337 /** 338 * pcc_mbox_probe - Called when we find a match for the 339 * PCCT platform device. This is purely used to represent 340 * the PCCT as a virtual device for registering with the 341 * generic Mailbox framework. 342 * 343 * @pdev: Pointer to platform device returned when a match 344 * is found. 345 * 346 * Return: 0 for Success, else errno. 347 */ 348 static int pcc_mbox_probe(struct platform_device *pdev) 349 { 350 int ret = 0; 351 352 pcc_mbox_ctrl.chans = pcc_mbox_channels; 353 pcc_mbox_ctrl.ops = &pcc_chan_ops; 354 pcc_mbox_ctrl.txdone_poll = true; 355 pcc_mbox_ctrl.txpoll_period = 10; 356 pcc_mbox_ctrl.dev = &pdev->dev; 357 358 pr_info("Registering PCC driver as Mailbox controller\n"); 359 ret = mbox_controller_register(&pcc_mbox_ctrl); 360 361 if (ret) { 362 pr_err("Err registering PCC as Mailbox controller: %d\n", ret); 363 ret = -ENODEV; 364 } 365 366 return ret; 367 } 368 369 struct platform_driver pcc_mbox_driver = { 370 .probe = pcc_mbox_probe, 371 .driver = { 372 .name = "PCCT", 373 .owner = THIS_MODULE, 374 }, 375 }; 376 377 static int __init pcc_init(void) 378 { 379 int ret; 380 struct platform_device *pcc_pdev; 381 382 if (acpi_disabled) 383 return -ENODEV; 384 385 /* Check if PCC support is available. */ 386 ret = acpi_pcc_probe(); 387 388 if (ret) { 389 pr_debug("ACPI PCC probe failed.\n"); 390 return -ENODEV; 391 } 392 393 pcc_pdev = platform_create_bundle(&pcc_mbox_driver, 394 pcc_mbox_probe, NULL, 0, NULL, 0); 395 396 if (IS_ERR(pcc_pdev)) { 397 pr_debug("Err creating PCC platform bundle\n"); 398 return PTR_ERR(pcc_pdev); 399 } 400 401 return 0; 402 } 403 device_initcall(pcc_init); 404