linux/drivers/bus/fsl-mc/dprc.c
<<
>>
Prefs
   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 */
  22int 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}
  47EXPORT_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 */
  60int 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}
  73EXPORT_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 */
  85int 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 */
 123int 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 */
 159int 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 */
 191int 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 */
 233int 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 */
 262int 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 */
 300int 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}
 324EXPORT_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 */
 341int 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}
 380EXPORT_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 */
 394int 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}
 421EXPORT_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 */
 435int 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        int err;
 447
 448        /* prepare command */
 449        cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
 450                                          cmd_flags, token);
 451        cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;
 452        cmd_params->obj_id = cpu_to_le32(obj_id);
 453        cmd_params->region_index = region_index;
 454        strncpy(cmd_params->obj_type, obj_type, 16);
 455        cmd_params->obj_type[15] = '\0';
 456
 457        /* send command to mc*/
 458        err = mc_send_command(mc_io, &cmd);
 459        if (err)
 460                return err;
 461
 462        /* retrieve response parameters */
 463        rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;
 464        region_desc->base_offset = le64_to_cpu(rsp_params->base_addr);
 465        region_desc->size = le32_to_cpu(rsp_params->size);
 466
 467        return 0;
 468}
 469EXPORT_SYMBOL_GPL(dprc_get_obj_region);
 470
 471/**
 472 * dprc_get_api_version - Get Data Path Resource Container API version
 473 * @mc_io:      Pointer to Mc portal's I/O object
 474 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 475 * @major_ver:  Major version of Data Path Resource Container API
 476 * @minor_ver:  Minor version of Data Path Resource Container API
 477 *
 478 * Return:      '0' on Success; Error code otherwise.
 479 */
 480int dprc_get_api_version(struct fsl_mc_io *mc_io,
 481                         u32 cmd_flags,
 482                         u16 *major_ver,
 483                         u16 *minor_ver)
 484{
 485        struct fsl_mc_command cmd = { 0 };
 486        int err;
 487
 488        /* prepare command */
 489        cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
 490                                          cmd_flags, 0);
 491
 492        /* send command to mc */
 493        err = mc_send_command(mc_io, &cmd);
 494        if (err)
 495                return err;
 496
 497        /* retrieve response parameters */
 498        mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
 499
 500        return 0;
 501}
 502
 503/**
 504 * dprc_get_container_id - Get container ID associated with a given portal.
 505 * @mc_io:              Pointer to Mc portal's I/O object
 506 * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
 507 * @container_id:       Requested container id
 508 *
 509 * Return:      '0' on Success; Error code otherwise.
 510 */
 511int dprc_get_container_id(struct fsl_mc_io *mc_io,
 512                          u32 cmd_flags,
 513                          int *container_id)
 514{
 515        struct fsl_mc_command cmd = { 0 };
 516        int err;
 517
 518        /* prepare command */
 519        cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
 520                                          cmd_flags,
 521                                          0);
 522
 523        /* send command to mc*/
 524        err = mc_send_command(mc_io, &cmd);
 525        if (err)
 526                return err;
 527
 528        /* retrieve response parameters */
 529        *container_id = (int)mc_cmd_read_object_id(&cmd);
 530
 531        return 0;
 532}
 533