forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/ethernet/mellanox/mlxsw/i2c.c
....@@ -14,14 +14,17 @@
1414 #include "cmd.h"
1515 #include "core.h"
1616 #include "i2c.h"
17
+#include "resources.h"
1718
1819 #define MLXSW_I2C_CIR2_BASE 0x72000
1920 #define MLXSW_I2C_CIR_STATUS_OFF 0x18
2021 #define MLXSW_I2C_CIR2_OFF_STATUS (MLXSW_I2C_CIR2_BASE + \
2122 MLXSW_I2C_CIR_STATUS_OFF)
2223 #define MLXSW_I2C_OPMOD_SHIFT 12
24
+#define MLXSW_I2C_EVENT_BIT_SHIFT 22
2325 #define MLXSW_I2C_GO_BIT_SHIFT 23
2426 #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
27
+#define MLXSW_I2C_EVENT_BIT BIT(MLXSW_I2C_EVENT_BIT_SHIFT)
2528 #define MLXSW_I2C_GO_BIT BIT(MLXSW_I2C_GO_BIT_SHIFT)
2629 #define MLXSW_I2C_GO_OPMODE BIT(MLXSW_I2C_OPMOD_SHIFT)
2730 #define MLXSW_I2C_SET_IMM_CMD (MLXSW_I2C_GO_OPMODE | \
....@@ -33,20 +36,24 @@
3336 #define MLXSW_I2C_TLV_HDR_SIZE 0x10
3437 #define MLXSW_I2C_ADDR_WIDTH 4
3538 #define MLXSW_I2C_PUSH_CMD_SIZE (MLXSW_I2C_ADDR_WIDTH + 4)
39
+#define MLXSW_I2C_SET_EVENT_CMD (MLXSW_I2C_EVENT_BIT)
40
+#define MLXSW_I2C_PUSH_EVENT_CMD (MLXSW_I2C_GO_BIT | \
41
+ MLXSW_I2C_SET_EVENT_CMD)
3642 #define MLXSW_I2C_READ_SEMA_SIZE 4
3743 #define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
3844 #define MLXSW_I2C_MBOX_SIZE 20
3945 #define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
40
-#define MLXSW_I2C_MAX_BUFF_SIZE 32
4146 #define MLXSW_I2C_MBOX_OFFSET_BITS 20
4247 #define MLXSW_I2C_MBOX_SIZE_BITS 12
4348 #define MLXSW_I2C_ADDR_BUF_SIZE 4
44
-#define MLXSW_I2C_BLK_MAX 32
49
+#define MLXSW_I2C_BLK_DEF 32
4550 #define MLXSW_I2C_RETRY 5
4651 #define MLXSW_I2C_TIMEOUT_MSECS 5000
52
+#define MLXSW_I2C_MAX_DATA_SIZE 256
4753
4854 /**
4955 * struct mlxsw_i2c - device private data:
56
+ * @cmd: command attributes;
5057 * @cmd.mb_size_in: input mailbox size;
5158 * @cmd.mb_off_in: input mailbox offset in register space;
5259 * @cmd.mb_size_out: output mailbox size;
....@@ -55,6 +62,7 @@
5562 * @dev: I2C device;
5663 * @core: switch core pointer;
5764 * @bus_info: bus info block;
65
+ * @block_size: maximum block size allowed to pass to under layer;
5866 */
5967 struct mlxsw_i2c {
6068 struct {
....@@ -67,6 +75,7 @@
6775 struct device *dev;
6876 struct mlxsw_core *core;
6977 struct mlxsw_bus_info bus_info;
78
+ u16 block_size;
7079 };
7180
7281 #define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
....@@ -167,7 +176,7 @@
167176 return err > 0 ? 0 : err;
168177 }
169178
170
-/* Routine posts a command to ASIC though mail box. */
179
+/* Routine posts a command to ASIC through mail box. */
171180 static int mlxsw_i2c_write_cmd(struct i2c_client *client,
172181 struct mlxsw_i2c *mlxsw_i2c,
173182 int immediate)
....@@ -213,6 +222,66 @@
213222 return 0;
214223 }
215224
225
+/* Routine posts initialization command to ASIC through mail box. */
226
+static int
227
+mlxsw_i2c_write_init_cmd(struct i2c_client *client,
228
+ struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod)
229
+{
230
+ __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
231
+ 0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD)
232
+ };
233
+ __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
234
+ 0, 0, 0, 0, 0, 0,
235
+ cpu_to_be32(client->adapter->nr & 0xffff),
236
+ cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD)
237
+ };
238
+ struct i2c_msg push_cmd =
239
+ MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
240
+ MLXSW_I2C_PUSH_CMD_SIZE);
241
+ struct i2c_msg prep_cmd =
242
+ MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
243
+ u8 status;
244
+ int err;
245
+
246
+ push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode);
247
+ prep_cmd_buf[3] = cpu_to_be32(in_mod);
248
+ prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode);
249
+ mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
250
+ MLXSW_I2C_CIR2_BASE);
251
+ mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
252
+ MLXSW_I2C_CIR2_OFF_STATUS);
253
+
254
+ /* Prepare Command Interface Register for transaction */
255
+ err = i2c_transfer(client->adapter, &prep_cmd, 1);
256
+ if (err < 0)
257
+ return err;
258
+ else if (err != 1)
259
+ return -EIO;
260
+
261
+ /* Write out Command Interface Register GO bit to push transaction */
262
+ err = i2c_transfer(client->adapter, &push_cmd, 1);
263
+ if (err < 0)
264
+ return err;
265
+ else if (err != 1)
266
+ return -EIO;
267
+
268
+ /* Wait until go bit is cleared. */
269
+ err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
270
+ if (err) {
271
+ dev_err(&client->dev, "HW semaphore is not released");
272
+ return err;
273
+ }
274
+
275
+ /* Validate transaction completion status. */
276
+ if (status) {
277
+ dev_err(&client->dev, "Bad transaction completion status %x\n",
278
+ status);
279
+ return -EIO;
280
+ }
281
+
282
+ return 0;
283
+}
284
+
216285 /* Routine obtains mail box offsets from ASIC register space. */
217286 static int mlxsw_i2c_get_mbox(struct i2c_client *client,
218287 struct mlxsw_i2c *mlxsw_i2c)
....@@ -248,20 +317,26 @@
248317 struct i2c_client *client = to_i2c_client(dev);
249318 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
250319 unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
251
- u8 tran_buf[MLXSW_I2C_MAX_BUFF_SIZE + MLXSW_I2C_ADDR_BUF_SIZE];
252320 int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
253321 unsigned long end;
322
+ u8 *tran_buf;
254323 struct i2c_msg write_tran =
255
- MLXSW_I2C_WRITE_MSG(client, tran_buf, MLXSW_I2C_PUSH_CMD_SIZE);
324
+ MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);
256325 int err;
257326
327
+ tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,
328
+ GFP_KERNEL);
329
+ if (!tran_buf)
330
+ return -ENOMEM;
331
+
332
+ write_tran.buf = tran_buf;
258333 for (i = 0; i < num; i++) {
259
- chunk_size = (in_mbox_size > MLXSW_I2C_BLK_MAX) ?
260
- MLXSW_I2C_BLK_MAX : in_mbox_size;
334
+ chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?
335
+ mlxsw_i2c->block_size : in_mbox_size;
261336 write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
262337 mlxsw_i2c_set_slave_addr(tran_buf, off);
263338 memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
264
- MLXSW_I2C_BLK_MAX * i, chunk_size);
339
+ mlxsw_i2c->block_size * i, chunk_size);
265340
266341 j = 0;
267342 end = jiffies + timeout;
....@@ -275,9 +350,10 @@
275350 (j++ < MLXSW_I2C_RETRY));
276351
277352 if (err != 1) {
278
- if (!err)
353
+ if (!err) {
279354 err = -EIO;
280
- return err;
355
+ goto mlxsw_i2c_write_exit;
356
+ }
281357 }
282358
283359 off += chunk_size;
....@@ -288,30 +364,33 @@
288364 err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
289365 if (err) {
290366 dev_err(&client->dev, "Could not start transaction");
291
- return -EIO;
367
+ err = -EIO;
368
+ goto mlxsw_i2c_write_exit;
292369 }
293370
294371 /* Wait until go bit is cleared. */
295372 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
296373 if (err) {
297374 dev_err(&client->dev, "HW semaphore is not released");
298
- return err;
375
+ goto mlxsw_i2c_write_exit;
299376 }
300377
301378 /* Validate transaction completion status. */
302379 if (*p_status) {
303380 dev_err(&client->dev, "Bad transaction completion status %x\n",
304381 *p_status);
305
- return -EIO;
382
+ err = -EIO;
306383 }
307384
308
- return 0;
385
+mlxsw_i2c_write_exit:
386
+ kfree(tran_buf);
387
+ return err;
309388 }
310389
311390 /* Routine executes I2C command. */
312391 static int
313
-mlxsw_i2c_cmd(struct device *dev, size_t in_mbox_size, u8 *in_mbox,
314
- size_t out_mbox_size, u8 *out_mbox, u8 *status)
392
+mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
393
+ u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status)
315394 {
316395 struct i2c_client *client = to_i2c_client(dev);
317396 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
....@@ -326,31 +405,47 @@
326405
327406 WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
328407
329
- reg_size = mlxsw_i2c_get_reg_size(in_mbox);
330
- num = reg_size / MLXSW_I2C_BLK_MAX;
331
- if (reg_size % MLXSW_I2C_BLK_MAX)
332
- num++;
408
+ if (in_mbox) {
409
+ reg_size = mlxsw_i2c_get_reg_size(in_mbox);
410
+ num = reg_size / mlxsw_i2c->block_size;
411
+ if (reg_size % mlxsw_i2c->block_size)
412
+ num++;
333413
334
- if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
335
- dev_err(&client->dev, "Could not acquire lock");
336
- return -EINVAL;
337
- }
414
+ if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
415
+ dev_err(&client->dev, "Could not acquire lock");
416
+ return -EINVAL;
417
+ }
338418
339
- err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
340
- if (err)
341
- goto cmd_fail;
419
+ err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
420
+ if (err)
421
+ goto cmd_fail;
342422
343
- /* No out mailbox is case of write transaction. */
344
- if (!out_mbox) {
345
- mutex_unlock(&mlxsw_i2c->cmd.lock);
346
- return 0;
423
+ /* No out mailbox is case of write transaction. */
424
+ if (!out_mbox) {
425
+ mutex_unlock(&mlxsw_i2c->cmd.lock);
426
+ return 0;
427
+ }
428
+ } else {
429
+ /* No input mailbox is case of initialization query command. */
430
+ reg_size = MLXSW_I2C_MAX_DATA_SIZE;
431
+ num = reg_size / mlxsw_i2c->block_size;
432
+
433
+ if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
434
+ dev_err(&client->dev, "Could not acquire lock");
435
+ return -EINVAL;
436
+ }
437
+
438
+ err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,
439
+ in_mod);
440
+ if (err)
441
+ goto cmd_fail;
347442 }
348443
349444 /* Send read transaction to get output mailbox content. */
350445 read_tran[1].buf = out_mbox;
351446 for (i = 0; i < num; i++) {
352
- chunk_size = (reg_size > MLXSW_I2C_BLK_MAX) ?
353
- MLXSW_I2C_BLK_MAX : reg_size;
447
+ chunk_size = (reg_size > mlxsw_i2c->block_size) ?
448
+ mlxsw_i2c->block_size : reg_size;
354449 read_tran[1].len = chunk_size;
355450 mlxsw_i2c_set_slave_addr(tran_buf, off);
356451
....@@ -395,8 +490,8 @@
395490 {
396491 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
397492
398
- return mlxsw_i2c_cmd(mlxsw_i2c->dev, in_mbox_size, in_mbox,
399
- out_mbox_size, out_mbox, status);
493
+ return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size,
494
+ in_mbox, out_mbox_size, out_mbox, status);
400495 }
401496
402497 static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
....@@ -414,13 +509,34 @@
414509 static int
415510 mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
416511 const struct mlxsw_config_profile *profile,
417
- struct mlxsw_res *resources)
512
+ struct mlxsw_res *res)
418513 {
419514 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
515
+ char *mbox;
516
+ int err;
420517
421518 mlxsw_i2c->core = mlxsw_core;
422519
423
- return 0;
520
+ mbox = mlxsw_cmd_mbox_alloc();
521
+ if (!mbox)
522
+ return -ENOMEM;
523
+
524
+ err = mlxsw_cmd_query_fw(mlxsw_core, mbox);
525
+ if (err)
526
+ goto mbox_put;
527
+
528
+ mlxsw_i2c->bus_info.fw_rev.major =
529
+ mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox);
530
+ mlxsw_i2c->bus_info.fw_rev.minor =
531
+ mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox);
532
+ mlxsw_i2c->bus_info.fw_rev.subminor =
533
+ mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox);
534
+
535
+ err = mlxsw_core_resources_query(mlxsw_core, mbox, res);
536
+
537
+mbox_put:
538
+ mlxsw_cmd_mbox_free(mbox);
539
+ return err;
424540 }
425541
426542 static void mlxsw_i2c_fini(void *bus_priv)
....@@ -442,6 +558,7 @@
442558 static int mlxsw_i2c_probe(struct i2c_client *client,
443559 const struct i2c_device_id *id)
444560 {
561
+ const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
445562 struct mlxsw_i2c *mlxsw_i2c;
446563 u8 status;
447564 int err;
....@@ -449,6 +566,22 @@
449566 mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
450567 if (!mlxsw_i2c)
451568 return -ENOMEM;
569
+
570
+ if (quirks) {
571
+ if ((quirks->max_read_len &&
572
+ quirks->max_read_len < MLXSW_I2C_BLK_DEF) ||
573
+ (quirks->max_write_len &&
574
+ quirks->max_write_len < MLXSW_I2C_BLK_DEF)) {
575
+ dev_err(&client->dev, "Insufficient transaction buffer length\n");
576
+ return -EOPNOTSUPP;
577
+ }
578
+
579
+ mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
580
+ min_t(u16, quirks->max_read_len,
581
+ quirks->max_write_len));
582
+ } else {
583
+ mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;
584
+ }
452585
453586 i2c_set_clientdata(client, mlxsw_i2c);
454587 mutex_init(&mlxsw_i2c->cmd.lock);
....@@ -503,11 +636,12 @@
503636 mlxsw_i2c->bus_info.device_kind = id->name;
504637 mlxsw_i2c->bus_info.device_name = client->name;
505638 mlxsw_i2c->bus_info.dev = &client->dev;
639
+ mlxsw_i2c->bus_info.low_frequency = true;
506640 mlxsw_i2c->dev = &client->dev;
507641
508642 err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
509643 &mlxsw_i2c_bus, mlxsw_i2c, false,
510
- NULL);
644
+ NULL, NULL);
511645 if (err) {
512646 dev_err(&client->dev, "Fail to register core bus\n");
513647 return err;
....@@ -516,6 +650,7 @@
516650 return 0;
517651
518652 errout:
653
+ mutex_destroy(&mlxsw_i2c->cmd.lock);
519654 i2c_set_clientdata(client, NULL);
520655
521656 return err;