root/drivers/bus/fsl-mc/dprc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dprc_open
  2. dprc_close
  3. dprc_set_irq
  4. dprc_set_irq_enable
  5. dprc_set_irq_mask
  6. dprc_get_irq_status
  7. dprc_clear_irq_status
  8. dprc_get_attributes
  9. dprc_get_obj_count
  10. dprc_get_obj
  11. dprc_set_obj_irq
  12. dprc_get_obj_region
  13. dprc_get_api_version
  14. dprc_get_container_id

   1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
   2 /*
   3  * Copyright 2013-2016 Freescale Semiconductor Inc.
   4  *
   5  */
   6 #include <linux/kernel.h>
   7 #include <linux/fsl/mc.h>
   8 
   9 #include "fsl-mc-private.h"
  10 
  11 /**
  12  * dprc_open() - Open DPRC object for use
  13  * @mc_io:      Pointer to MC portal's I/O object
  14  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
  15  * @container_id: Container ID to open
  16  * @token:      Returned token of DPRC object
  17  *
  18  * Return:      '0' on Success; Error code otherwise.
  19  *
  20  * @warning     Required before any operation on the object.
  21  */
  22 int dprc_open(struct fsl_mc_io *mc_io,
  23               u32 cmd_flags,
  24               int container_id,
  25               u16 *token)
  26 {
  27         struct fsl_mc_command cmd = { 0 };
  28         struct dprc_cmd_open *cmd_params;
  29         int err;
  30 
  31         /* prepare command */
  32         cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,
  33                                           0);
  34         cmd_params = (struct dprc_cmd_open *)cmd.params;
  35         cmd_params->container_id = cpu_to_le32(container_id);
  36 
  37         /* send command to mc*/
  38         err = mc_send_command(mc_io, &cmd);
  39         if (err)
  40                 return err;
  41 
  42         /* retrieve response parameters */
  43         *token = mc_cmd_hdr_read_token(&cmd);
  44 
  45         return 0;
  46 }
  47 EXPORT_SYMBOL_GPL(dprc_open);
  48 
  49 /**
  50  * dprc_close() - Close the control session of the object
  51  * @mc_io:      Pointer to MC portal's I/O object
  52  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
  53  * @token:      Token of DPRC object
  54  *
  55  * After this function is called, no further operations are
  56  * allowed on the object without opening a new control session.
  57  *
  58  * Return:      '0' on Success; Error code otherwise.
  59  */
  60 int dprc_close(struct fsl_mc_io *mc_io,
  61                u32 cmd_flags,
  62                u16 token)
  63 {
  64         struct fsl_mc_command cmd = { 0 };
  65 
  66         /* prepare command */
  67         cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,
  68                                           token);
  69 
  70         /* send command to mc*/
  71         return mc_send_command(mc_io, &cmd);
  72 }
  73 EXPORT_SYMBOL_GPL(dprc_close);
  74 
  75 /**
  76  * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.
  77  * @mc_io:      Pointer to MC portal's I/O object
  78  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
  79  * @token:      Token of DPRC object
  80  * @irq_index:  Identifies the interrupt index to configure
  81  * @irq_cfg:    IRQ configuration
  82  *
  83  * Return:      '0' on Success; Error code otherwise.
  84  */
  85 int dprc_set_irq(struct fsl_mc_io *mc_io,
  86                  u32 cmd_flags,
  87                  u16 token,
  88                  u8 irq_index,
  89                  struct dprc_irq_cfg *irq_cfg)
  90 {
  91         struct fsl_mc_command cmd = { 0 };
  92         struct dprc_cmd_set_irq *cmd_params;
  93 
  94         /* prepare command */
  95         cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,
  96                                           cmd_flags,
  97                                           token);
  98         cmd_params = (struct dprc_cmd_set_irq *)cmd.params;
  99         cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
 100         cmd_params->irq_index = irq_index;
 101         cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
 102         cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
 103 
 104         /* send command to mc*/
 105         return mc_send_command(mc_io, &cmd);
 106 }
 107 
 108 /**
 109  * dprc_set_irq_enable() - Set overall interrupt state.
 110  * @mc_io:      Pointer to MC portal's I/O object
 111  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 112  * @token:      Token of DPRC object
 113  * @irq_index:  The interrupt index to configure
 114  * @en:         Interrupt state - enable = 1, disable = 0
 115  *
 116  * Allows GPP software to control when interrupts are generated.
 117  * Each interrupt can have up to 32 causes.  The enable/disable control's the
 118  * overall interrupt state. if the interrupt is disabled no causes will cause
 119  * an interrupt.
 120  *
 121  * Return:      '0' on Success; Error code otherwise.
 122  */
 123 int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
 124                         u32 cmd_flags,
 125                         u16 token,
 126                         u8 irq_index,
 127                         u8 en)
 128 {
 129         struct fsl_mc_command cmd = { 0 };
 130         struct dprc_cmd_set_irq_enable *cmd_params;
 131 
 132         /* prepare command */
 133         cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,
 134                                           cmd_flags, token);
 135         cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params;
 136         cmd_params->enable = en & DPRC_ENABLE;
 137         cmd_params->irq_index = irq_index;
 138 
 139         /* send command to mc*/
 140         return mc_send_command(mc_io, &cmd);
 141 }
 142 
 143 /**
 144  * dprc_set_irq_mask() - Set interrupt mask.
 145  * @mc_io:      Pointer to MC portal's I/O object
 146  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 147  * @token:      Token of DPRC object
 148  * @irq_index:  The interrupt index to configure
 149  * @mask:       event mask to trigger interrupt;
 150  *                      each bit:
 151  *                              0 = ignore event
 152  *                              1 = consider event for asserting irq
 153  *
 154  * Every interrupt can have up to 32 causes and the interrupt model supports
 155  * masking/unmasking each cause independently
 156  *
 157  * Return:      '0' on Success; Error code otherwise.
 158  */
 159 int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
 160                       u32 cmd_flags,
 161                       u16 token,
 162                       u8 irq_index,
 163                       u32 mask)
 164 {
 165         struct fsl_mc_command cmd = { 0 };
 166         struct dprc_cmd_set_irq_mask *cmd_params;
 167 
 168         /* prepare command */
 169         cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,
 170                                           cmd_flags, token);
 171         cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params;
 172         cmd_params->mask = cpu_to_le32(mask);
 173         cmd_params->irq_index = irq_index;
 174 
 175         /* send command to mc*/
 176         return mc_send_command(mc_io, &cmd);
 177 }
 178 
 179 /**
 180  * dprc_get_irq_status() - Get the current status of any pending interrupts.
 181  * @mc_io:      Pointer to MC portal's I/O object
 182  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 183  * @token:      Token of DPRC object
 184  * @irq_index:  The interrupt index to configure
 185  * @status:     Returned interrupts status - one bit per cause:
 186  *                      0 = no interrupt pending
 187  *                      1 = interrupt pending
 188  *
 189  * Return:      '0' on Success; Error code otherwise.
 190  */
 191 int dprc_get_irq_status(struct fsl_mc_io *mc_io,
 192                         u32 cmd_flags,
 193                         u16 token,
 194                         u8 irq_index,
 195                         u32 *status)
 196 {
 197         struct fsl_mc_command cmd = { 0 };
 198         struct dprc_cmd_get_irq_status *cmd_params;
 199         struct dprc_rsp_get_irq_status *rsp_params;
 200         int err;
 201 
 202         /* prepare command */
 203         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
 204                                           cmd_flags, token);
 205         cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params;
 206         cmd_params->status = cpu_to_le32(*status);
 207         cmd_params->irq_index = irq_index;
 208 
 209         /* send command to mc*/
 210         err = mc_send_command(mc_io, &cmd);
 211         if (err)
 212                 return err;
 213 
 214         /* retrieve response parameters */
 215         rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params;
 216         *status = le32_to_cpu(rsp_params->status);
 217 
 218         return 0;
 219 }
 220 
 221 /**
 222  * dprc_clear_irq_status() - Clear a pending interrupt's status
 223  * @mc_io:      Pointer to MC portal's I/O object
 224  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 225  * @token:      Token of DPRC object
 226  * @irq_index:  The interrupt index to configure
 227  * @status:     bits to clear (W1C) - one bit per cause:
 228  *                                      0 = don't change
 229  *                                      1 = clear status bit
 230  *
 231  * Return:      '0' on Success; Error code otherwise.
 232  */
 233 int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
 234                           u32 cmd_flags,
 235                           u16 token,
 236                           u8 irq_index,
 237                           u32 status)
 238 {
 239         struct fsl_mc_command cmd = { 0 };
 240         struct dprc_cmd_clear_irq_status *cmd_params;
 241 
 242         /* prepare command */
 243         cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,
 244                                           cmd_flags, token);
 245         cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params;
 246         cmd_params->status = cpu_to_le32(status);
 247         cmd_params->irq_index = irq_index;
 248 
 249         /* send command to mc*/
 250         return mc_send_command(mc_io, &cmd);
 251 }
 252 
 253 /**
 254  * dprc_get_attributes() - Obtains container attributes
 255  * @mc_io:      Pointer to MC portal's I/O object
 256  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 257  * @token:      Token of DPRC object
 258  * @attributes  Returned container attributes
 259  *
 260  * Return:     '0' on Success; Error code otherwise.
 261  */
 262 int dprc_get_attributes(struct fsl_mc_io *mc_io,
 263                         u32 cmd_flags,
 264                         u16 token,
 265                         struct dprc_attributes *attr)
 266 {
 267         struct fsl_mc_command cmd = { 0 };
 268         struct dprc_rsp_get_attributes *rsp_params;
 269         int err;
 270 
 271         /* prepare command */
 272         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
 273                                           cmd_flags,
 274                                           token);
 275 
 276         /* send command to mc*/
 277         err = mc_send_command(mc_io, &cmd);
 278         if (err)
 279                 return err;
 280 
 281         /* retrieve response parameters */
 282         rsp_params = (struct dprc_rsp_get_attributes *)cmd.params;
 283         attr->container_id = le32_to_cpu(rsp_params->container_id);
 284         attr->icid = le16_to_cpu(rsp_params->icid);
 285         attr->options = le32_to_cpu(rsp_params->options);
 286         attr->portal_id = le32_to_cpu(rsp_params->portal_id);
 287 
 288         return 0;
 289 }
 290 
 291 /**
 292  * dprc_get_obj_count() - Obtains the number of objects in the DPRC
 293  * @mc_io:      Pointer to MC portal's I/O object
 294  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 295  * @token:      Token of DPRC object
 296  * @obj_count:  Number of objects assigned to the DPRC
 297  *
 298  * Return:      '0' on Success; Error code otherwise.
 299  */
 300 int dprc_get_obj_count(struct fsl_mc_io *mc_io,
 301                        u32 cmd_flags,
 302                        u16 token,
 303                        int *obj_count)
 304 {
 305         struct fsl_mc_command cmd = { 0 };
 306         struct dprc_rsp_get_obj_count *rsp_params;
 307         int err;
 308 
 309         /* prepare command */
 310         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
 311                                           cmd_flags, token);
 312 
 313         /* send command to mc*/
 314         err = mc_send_command(mc_io, &cmd);
 315         if (err)
 316                 return err;
 317 
 318         /* retrieve response parameters */
 319         rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params;
 320         *obj_count = le32_to_cpu(rsp_params->obj_count);
 321 
 322         return 0;
 323 }
 324 EXPORT_SYMBOL_GPL(dprc_get_obj_count);
 325 
 326 /**
 327  * dprc_get_obj() - Get general information on an object
 328  * @mc_io:      Pointer to MC portal's I/O object
 329  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 330  * @token:      Token of DPRC object
 331  * @obj_index:  Index of the object to be queried (< obj_count)
 332  * @obj_desc:   Returns the requested object descriptor
 333  *
 334  * The object descriptors are retrieved one by one by incrementing
 335  * obj_index up to (not including) the value of obj_count returned
 336  * from dprc_get_obj_count(). dprc_get_obj_count() must
 337  * be called prior to dprc_get_obj().
 338  *
 339  * Return:      '0' on Success; Error code otherwise.
 340  */
 341 int dprc_get_obj(struct fsl_mc_io *mc_io,
 342                  u32 cmd_flags,
 343                  u16 token,
 344                  int obj_index,
 345                  struct fsl_mc_obj_desc *obj_desc)
 346 {
 347         struct fsl_mc_command cmd = { 0 };
 348         struct dprc_cmd_get_obj *cmd_params;
 349         struct dprc_rsp_get_obj *rsp_params;
 350         int err;
 351 
 352         /* prepare command */
 353         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
 354                                           cmd_flags,
 355                                           token);
 356         cmd_params = (struct dprc_cmd_get_obj *)cmd.params;
 357         cmd_params->obj_index = cpu_to_le32(obj_index);
 358 
 359         /* send command to mc*/
 360         err = mc_send_command(mc_io, &cmd);
 361         if (err)
 362                 return err;
 363 
 364         /* retrieve response parameters */
 365         rsp_params = (struct dprc_rsp_get_obj *)cmd.params;
 366         obj_desc->id = le32_to_cpu(rsp_params->id);
 367         obj_desc->vendor = le16_to_cpu(rsp_params->vendor);
 368         obj_desc->irq_count = rsp_params->irq_count;
 369         obj_desc->region_count = rsp_params->region_count;
 370         obj_desc->state = le32_to_cpu(rsp_params->state);
 371         obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
 372         obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
 373         obj_desc->flags = le16_to_cpu(rsp_params->flags);
 374         strncpy(obj_desc->type, rsp_params->type, 16);
 375         obj_desc->type[15] = '\0';
 376         strncpy(obj_desc->label, rsp_params->label, 16);
 377         obj_desc->label[15] = '\0';
 378         return 0;
 379 }
 380 EXPORT_SYMBOL_GPL(dprc_get_obj);
 381 
 382 /**
 383  * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt.
 384  * @mc_io:      Pointer to MC portal's I/O object
 385  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 386  * @token:      Token of DPRC object
 387  * @obj_type:   Type of the object to set its IRQ
 388  * @obj_id:     ID of the object to set its IRQ
 389  * @irq_index:  The interrupt index to configure
 390  * @irq_cfg:    IRQ configuration
 391  *
 392  * Return:      '0' on Success; Error code otherwise.
 393  */
 394 int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
 395                      u32 cmd_flags,
 396                      u16 token,
 397                      char *obj_type,
 398                      int obj_id,
 399                      u8 irq_index,
 400                      struct dprc_irq_cfg *irq_cfg)
 401 {
 402         struct fsl_mc_command cmd = { 0 };
 403         struct dprc_cmd_set_obj_irq *cmd_params;
 404 
 405         /* prepare command */
 406         cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ,
 407                                           cmd_flags,
 408                                           token);
 409         cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params;
 410         cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
 411         cmd_params->irq_index = irq_index;
 412         cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
 413         cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
 414         cmd_params->obj_id = cpu_to_le32(obj_id);
 415         strncpy(cmd_params->obj_type, obj_type, 16);
 416         cmd_params->obj_type[15] = '\0';
 417 
 418         /* send command to mc*/
 419         return mc_send_command(mc_io, &cmd);
 420 }
 421 EXPORT_SYMBOL_GPL(dprc_set_obj_irq);
 422 
 423 /**
 424  * dprc_get_obj_region() - Get region information for a specified object.
 425  * @mc_io:      Pointer to MC portal's I/O object
 426  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 427  * @token:      Token of DPRC object
 428  * @obj_type;   Object type as returned in dprc_get_obj()
 429  * @obj_id:     Unique object instance as returned in dprc_get_obj()
 430  * @region_index: The specific region to query
 431  * @region_desc:  Returns the requested region descriptor
 432  *
 433  * Return:      '0' on Success; Error code otherwise.
 434  */
 435 int dprc_get_obj_region(struct fsl_mc_io *mc_io,
 436                         u32 cmd_flags,
 437                         u16 token,
 438                         char *obj_type,
 439                         int obj_id,
 440                         u8 region_index,
 441                         struct dprc_region_desc *region_desc)
 442 {
 443         struct fsl_mc_command cmd = { 0 };
 444         struct dprc_cmd_get_obj_region *cmd_params;
 445         struct dprc_rsp_get_obj_region *rsp_params;
 446         u16 major_ver, minor_ver;
 447         int err;
 448 
 449         /* prepare command */
 450         err = dprc_get_api_version(mc_io, 0,
 451                                      &major_ver,
 452                                      &minor_ver);
 453         if (err)
 454                 return err;
 455 
 456         /**
 457          * MC API version 6.3 introduced a new field to the region
 458          * descriptor: base_address. If the older API is in use then the base
 459          * address is set to zero to indicate it needs to be obtained elsewhere
 460          * (typically the device tree).
 461          */
 462         if (major_ver > 6 || (major_ver == 6 && minor_ver >= 3))
 463                 cmd.header =
 464                         mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2,
 465                                              cmd_flags, token);
 466         else
 467                 cmd.header =
 468                         mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
 469                                              cmd_flags, token);
 470 
 471         cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;
 472         cmd_params->obj_id = cpu_to_le32(obj_id);
 473         cmd_params->region_index = region_index;
 474         strncpy(cmd_params->obj_type, obj_type, 16);
 475         cmd_params->obj_type[15] = '\0';
 476 
 477         /* send command to mc*/
 478         err = mc_send_command(mc_io, &cmd);
 479         if (err)
 480                 return err;
 481 
 482         /* retrieve response parameters */
 483         rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;
 484         region_desc->base_offset = le64_to_cpu(rsp_params->base_offset);
 485         region_desc->size = le32_to_cpu(rsp_params->size);
 486         if (major_ver > 6 || (major_ver == 6 && minor_ver >= 3))
 487                 region_desc->base_address = le64_to_cpu(rsp_params->base_addr);
 488         else
 489                 region_desc->base_address = 0;
 490 
 491         return 0;
 492 }
 493 EXPORT_SYMBOL_GPL(dprc_get_obj_region);
 494 
 495 /**
 496  * dprc_get_api_version - Get Data Path Resource Container API version
 497  * @mc_io:      Pointer to Mc portal's I/O object
 498  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 499  * @major_ver:  Major version of Data Path Resource Container API
 500  * @minor_ver:  Minor version of Data Path Resource Container API
 501  *
 502  * Return:      '0' on Success; Error code otherwise.
 503  */
 504 int dprc_get_api_version(struct fsl_mc_io *mc_io,
 505                          u32 cmd_flags,
 506                          u16 *major_ver,
 507                          u16 *minor_ver)
 508 {
 509         struct fsl_mc_command cmd = { 0 };
 510         int err;
 511 
 512         /* prepare command */
 513         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
 514                                           cmd_flags, 0);
 515 
 516         /* send command to mc */
 517         err = mc_send_command(mc_io, &cmd);
 518         if (err)
 519                 return err;
 520 
 521         /* retrieve response parameters */
 522         mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
 523 
 524         return 0;
 525 }
 526 
 527 /**
 528  * dprc_get_container_id - Get container ID associated with a given portal.
 529  * @mc_io:              Pointer to Mc portal's I/O object
 530  * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
 531  * @container_id:       Requested container id
 532  *
 533  * Return:      '0' on Success; Error code otherwise.
 534  */
 535 int dprc_get_container_id(struct fsl_mc_io *mc_io,
 536                           u32 cmd_flags,
 537                           int *container_id)
 538 {
 539         struct fsl_mc_command cmd = { 0 };
 540         int err;
 541 
 542         /* prepare command */
 543         cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
 544                                           cmd_flags,
 545                                           0);
 546 
 547         /* send command to mc*/
 548         err = mc_send_command(mc_io, &cmd);
 549         if (err)
 550                 return err;
 551 
 552         /* retrieve response parameters */
 553         *container_id = (int)mc_cmd_read_object_id(&cmd);
 554 
 555         return 0;
 556 }

/* [<][>][^][v][top][bottom][index][help] */