summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Forlin <per.forlin@stericsson.com>2011-10-14 13:54:36 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:58 +0200
commit8824cdd4e414fbd49edb83a9805784e994645b0c (patch)
treee7d9f2a2b1aad11130e850a28029e8d076259a25
parent2ba5452332b14b39eb20d54c5add45f81ed341fd (diff)
mmc: mmc_test: add 4 byte alignment tests
Add test cases to verify alignment with 4 bytes and 32 bytes for sg element lengths and memory addresses. These tests were added to investigate DMA constraints when transferring buffers that are not aligned with 32 bytes. ST-Ericsson ID: 363565 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I6363a018647f22e5d69920af2cb30dfe2b2a699e Signed-off-by: Per Forlin <per.forlin@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34362 Reviewed-by: QATOOLS Reviewed-by: Ulf HANSSON <ulf.hansson@stericsson.com>
-rw-r--r--drivers/mmc/card/mmc_test.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 759714ed6be..6622f2e6e05 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -1253,6 +1253,130 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test)
return 0;
}
+
+/* helper function for various address alignment and sg length alignment */
+static int mmc_test_align_multi(struct mmc_test_card *test, bool do_write,
+ struct scatterlist *sg,
+ u32 *sizes, int sg_len, int offset)
+{
+ int ret, i;
+ unsigned int size;
+ u32 buf_off;
+ u32 sg_size;
+
+ if (test->card->host->max_blk_count == 1)
+ return RESULT_UNSUP_HOST;
+
+ size = PAGE_SIZE * 2;
+ size = min(size, test->card->host->max_req_size);
+ size = min(size, test->card->host->max_seg_size);
+ size = min(size, test->card->host->max_blk_count * 512);
+ size -= offset;
+ size -= size % 512;
+
+ if (size < 1024)
+ return RESULT_UNSUP_HOST;
+
+ for (i = 0, sg_size = 0;
+ i < sg_len && sg_size + sizes[i] < size; i++)
+ sg_size += sizes[i];
+
+ if (sg_size < size)
+ sizes[i-1] += size - sg_size;
+ sg_len = i;
+
+ sg_init_table(sg, sg_len);
+ for (i = 0, buf_off = offset; i < sg_len; i++) {
+ sg_set_buf(&sg[i], test->buffer + buf_off, sizes[i]);
+ buf_off += sizes[i];
+ }
+
+ ret = mmc_test_transfer(test, sg, sg_len, 0, size/512, 512, do_write);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int mmc_test_align_length_32(struct mmc_test_card *test, bool do_write)
+{
+ u32 sizes[] = {512, 32*1, 32*2, 32*3, 32*4, 32*5, 32*6, 32*7,
+ 32*8, 32*9, 32*10, 32*11, 32*12, 32*13, 2048};
+ struct scatterlist sg[ARRAY_SIZE(sizes)];
+
+ return mmc_test_align_multi(test, do_write, sg, sizes,
+ ARRAY_SIZE(sg), 0);
+}
+
+static int mmc_test_align_length_4(struct mmc_test_card *test, bool do_write)
+{
+ u32 sizes[] = {512, 4*1, 4*2, 4*3, 4*4, 4*5, 4*6, 4*7,
+ 4*8, 4*9, 520, 1040, 2080};
+ struct scatterlist sg[ARRAY_SIZE(sizes)];
+
+ return mmc_test_align_multi(test, do_write, sg, sizes,
+ ARRAY_SIZE(sg), 0);
+}
+
+static int mmc_test_align_length_4_write(struct mmc_test_card *test)
+{
+ bool do_write = true;
+ return mmc_test_align_length_4(test, do_write);
+}
+
+static int mmc_test_align_length_4_read(struct mmc_test_card *test)
+{
+ bool do_write = false;
+ return mmc_test_align_length_4(test, do_write);
+}
+
+static int mmc_test_align_length_32_write(struct mmc_test_card *test)
+{
+ bool do_write = true;
+ return mmc_test_align_length_32(test, do_write);
+}
+
+static int mmc_test_align_length_32_read(struct mmc_test_card *test)
+{
+ bool do_write = false;
+ return mmc_test_align_length_32(test, do_write);
+}
+
+/* helper function for testing address alignment */
+static int mmc_test_align_address(struct mmc_test_card *test, bool do_write,
+ u32 offset)
+{
+ u32 sizes[] = {512, 512, 1024, 1024, 2048};
+ struct scatterlist sg[ARRAY_SIZE(sizes)];
+
+ return mmc_test_align_multi(test, do_write, sg,
+ sizes, ARRAY_SIZE(sg), offset);
+}
+
+static int mmc_test_align_address_4_write(struct mmc_test_card *test)
+{
+ bool do_write = true;
+ return mmc_test_align_address(test, do_write, 4);
+}
+
+static int mmc_test_align_address_4_read(struct mmc_test_card *test)
+{
+ bool do_write = false;
+ return mmc_test_align_address(test, do_write, 4);
+}
+
+static int mmc_test_align_address_32_write(struct mmc_test_card *test)
+{
+ bool do_write = true;
+ return mmc_test_align_address(test, do_write, 32);
+}
+
+static int mmc_test_align_address_32_read(struct mmc_test_card *test)
+{
+ bool do_write = false;
+ return mmc_test_align_address(test, do_write, 32);
+}
+
static int mmc_test_xfersize_write(struct mmc_test_card *test)
{
int ret;
@@ -2451,6 +2575,62 @@ static const struct mmc_test_case mmc_test_cases[] = {
},
{
+ .name = "4 bytes aligned sg-element length write",
+ .prepare = mmc_test_prepare_write,
+ .run = mmc_test_align_length_4_write,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "4 bytes aligned sg-element length read",
+ .prepare = mmc_test_prepare_read,
+ .run = mmc_test_align_length_4_read,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "32 bytes aligned sg-element length write",
+ .prepare = mmc_test_prepare_write,
+ .run = mmc_test_align_length_32_write,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "32 bytes aligned sg-element length read",
+ .prepare = mmc_test_prepare_read,
+ .run = mmc_test_align_length_32_read,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "4 bytes aligned sg-element address write",
+ .prepare = mmc_test_prepare_write,
+ .run = mmc_test_align_address_4_write,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "4 bytes aligned sg-element address read",
+ .prepare = mmc_test_prepare_read,
+ .run = mmc_test_align_address_4_read,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "32 bytes aligned sg-element address write",
+ .prepare = mmc_test_prepare_write,
+ .run = mmc_test_align_address_32_write,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
+ .name = "32 bytes aligned sg-element address read",
+ .prepare = mmc_test_prepare_read,
+ .run = mmc_test_align_address_32_read,
+ .cleanup = mmc_test_cleanup,
+ },
+
+ {
.name = "Correct xfer_size at write (start failure)",
.run = mmc_test_xfersize_write,
},