nand_generic_inter.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <stdint.h>
  32. #include <printf.h>
  33. #include <malloc.h>
  34. #include <string.h>
  35. #ifdef MTK_GPT_SCHEME_SUPPORT
  36. #include <platform/partition.h>
  37. #else
  38. #include <mt_partition.h>
  39. #endif
  40. #include <platform/errno.h>
  41. #include <debug.h>
  42. #include <kernel/mutex.h>
  43. #define PMT 1
  44. __attribute__ ((aligned(64))) static uchar mt_part_buf[16384];
  45. #define GB (1024 * MB)
  46. static part_dev_t *mt_part_dev = NULL;
  47. static mutex_t g_part_lock;
  48. extern void part_init_pmt(unsigned long totalblks,part_dev_t *dev);
  49. static int mt_part_generic_read(part_dev_t *dev, u64 src, uchar *dst, int size, unsigned int part_id)
  50. {
  51. int dev_id = dev->id;
  52. uchar *buf = &mt_part_buf[0];
  53. block_dev_desc_t *blkdev = dev->blkdev;
  54. u64 end, part_start, part_end, part_len, aligned_start, aligned_end;
  55. ulong blknr, blkcnt;
  56. if (!blkdev) {
  57. dprintf(CRITICAL, "No block device registered\n");
  58. return -ENODEV;
  59. }
  60. if (size == 0) {
  61. return 0;
  62. }
  63. end = src + size;
  64. part_start = src & ((u64)blkdev->blksz - 1);
  65. part_end = end & ((u64)blkdev->blksz - 1);
  66. aligned_start = src & ~((u64)blkdev->blksz - 1);
  67. aligned_end = end & ~((u64)blkdev->blksz - 1);
  68. /* dprintf(INFO, "%s part_start:0x%x size:0x%x\n", __func__, part_start, size); */
  69. mutex_acquire(&g_part_lock);
  70. if (part_start) {
  71. blknr = (ulong)(aligned_start >> blkdev->blk_bits);
  72. part_len = (u64)blkdev->blksz - part_start;
  73. if (part_len>(u64)size) {
  74. part_len = (u64)size;
  75. }
  76. if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id))!= 1) {
  77. mutex_release(&g_part_lock);
  78. return -EIO;
  79. }
  80. memcpy(dst, buf + part_start, part_len);
  81. dst += part_len;
  82. src += part_len;
  83. }
  84. aligned_start = src & ~((u64)blkdev->blksz - 1);
  85. blknr = (ulong)(aligned_start >> blkdev->blk_bits);
  86. blkcnt = (ulong)((aligned_end - aligned_start) >> blkdev->blk_bits);
  87. if (blkcnt != 0) {
  88. if ((blkdev->block_read(dev_id, blknr, blkcnt, (unsigned long *)(dst), part_id)) != blkcnt) {
  89. mutex_release(&g_part_lock);
  90. return -EIO;
  91. }
  92. }
  93. src += ((u64)blkcnt << blkdev->blk_bits);
  94. dst += ((u64)blkcnt << blkdev->blk_bits);
  95. if (part_end && src < end) {
  96. blknr = (ulong)(aligned_end >> blkdev->blk_bits);
  97. if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
  98. mutex_release(&g_part_lock);
  99. return -EIO;
  100. }
  101. memcpy(dst, buf, part_end);
  102. }
  103. mutex_release(&g_part_lock);
  104. return size;
  105. }
  106. static int mt_part_generic_write(part_dev_t *dev, uchar *src, u64 dst, int size, unsigned int part_id)
  107. {
  108. int dev_id = dev->id;
  109. uchar *buf = &mt_part_buf[0];
  110. block_dev_desc_t *blkdev = dev->blkdev;
  111. u64 end, part_start, part_end, part_len, aligned_start, aligned_end;
  112. ulong blknr, blkcnt;
  113. if (!blkdev) {
  114. dprintf(CRITICAL, "No block device registered\n");
  115. return -ENODEV;
  116. }
  117. if (size == 0) {
  118. return 0;
  119. }
  120. end = dst + size;
  121. part_start = dst & ((u64)blkdev->blksz - 1);
  122. part_end = end & ((u64)blkdev->blksz - 1);
  123. aligned_start = dst & ~((u64)blkdev->blksz - 1);
  124. aligned_end = end & ~((u64)blkdev->blksz - 1);
  125. /* dprintf(INFO, "%s part_start:0x%x size:0x%x\n", __func__, part_start, size); */
  126. mutex_acquire(&g_part_lock);
  127. if (part_start) {
  128. blknr = (ulong)(aligned_start >> blkdev->blk_bits);
  129. part_len = (u64)blkdev->blksz - part_start;
  130. if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
  131. mutex_release(&g_part_lock);
  132. return -EIO;
  133. }
  134. memcpy(buf + part_start, src, part_len);
  135. if ((blkdev->block_write(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
  136. mutex_release(&g_part_lock);
  137. return -EIO;
  138. }
  139. dst += part_len;
  140. src += part_len;
  141. }
  142. aligned_start = dst & ~((u64)blkdev->blksz - 1);
  143. blknr = (ulong)(aligned_start >> blkdev->blk_bits);
  144. blkcnt = (ulong)((aligned_end - aligned_start) >> blkdev->blk_bits);
  145. if ((blkdev->block_write(dev_id, blknr, blkcnt, (unsigned long *)(src), part_id)) != blkcnt) {
  146. mutex_release(&g_part_lock);
  147. return -EIO;
  148. }
  149. src += ((u64)blkcnt << blkdev->blk_bits);
  150. dst += ((u64)blkcnt << blkdev->blk_bits);
  151. if (part_end && dst < end) {
  152. blknr = (u64)(aligned_end >> blkdev->blk_bits);
  153. if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
  154. mutex_release(&g_part_lock);
  155. return -EIO;
  156. }
  157. memcpy(buf, src, part_end);
  158. if ((blkdev->block_write(dev_id, blknr, 1, (unsigned long*)buf, part_id))!= 1) {
  159. mutex_release(&g_part_lock);
  160. return -EIO;
  161. }
  162. }
  163. mutex_release(&g_part_lock);
  164. return size;
  165. }
  166. int mt_part_register_device(part_dev_t *dev)
  167. {
  168. /* dprintf(INFO, "[mt_part_register_device]\n"); */
  169. if (!mt_part_dev) {
  170. if (!dev->read) {
  171. dev->read = mt_part_generic_read;
  172. }
  173. if (!dev->write) {
  174. dev->write = mt_part_generic_write;
  175. }
  176. mt_part_dev = dev;
  177. mutex_init(&g_part_lock);
  178. dprintf(INFO, "[mt_part_register_device]malloc %d : mt_part_buf:%x mt_part_dev:0x%lx\n",
  179. (16384), mt_part_buf, mt_part_dev);
  180. #ifdef PMT
  181. part_init_pmt(BLK_NUM(1 * GB), dev);
  182. #else
  183. mt_part_init(BLK_NUM(1 * GB));
  184. #endif
  185. }
  186. return 0;
  187. }
  188. part_dev_t *mt_part_get_device(void)
  189. {
  190. if (mt_part_dev && !mt_part_dev->init && mt_part_dev->init_dev) {
  191. mt_part_dev->init_dev(mt_part_dev->id);
  192. mt_part_dev->init = 1;
  193. }
  194. return mt_part_dev;
  195. }